> If the program is a file beginning with ‘#!', the remainder of the first line specifies an interpreter for the program. The shell will execute the specified interpreter on operating systems that do not handle this executable format in the kernel.
Taking a quick look at the source in Src/exec.c:
execve(pth, argv, newenvp);
// [...]
if ((eno = errno) == ENOEXEC || eno == ENOENT) {
// [...]
if (ct >= 2 && execvebuf[0] == '#' && execvebuf[1] == '!') {
// [...]
(pprog = pathprog(ptr2, NULL))) {
I guess at some point someone added that `|| eno == ENOENT` and the docs weren't updated.[1] https://sourceforge.net/p/zsh/code/ci/29ed6c7e3ab32da20f528a...
[2] https://sourceforge.net/p/zsh/code/ci/29ed6c7e3ab32da20f528a...
I don't have fish installed and can't be bothered to go that far, but I suspect they're right about that as well.
https://github.com/torvalds/linux/blob/v6.17/fs/binfmt_scrip...
I think it makes it to calling open_exec but there's a test for BINPRM_FLAGS_PATH_INACCESSIBLE, which doesn't seem relevant since 'bash' isn't like '/dev/fd/<fd>/..', but does provoke an ENOENT.
https://github.com/torvalds/linux/blob/v6.17/fs/exec.c#L1445
Maybe someone else can explain it, I'd enjoy the details, and ran out of steam.