Well, the POSIX standard has nothing to say either way:
One common historical implementation is that the execl(), execv(),
execle(), and execve() functions return an [ENOEXEC] error for any
file not recognizable as executable, including a shell script. When
the execlp() and execvp() functions encounter such a file, they assume
the file to be a shell script and invoke a known command interpreter
to interpret such files. This is now required by POSIX.1-2008. These
implementations of execvp() and execlp() only give the [ENOEXEC] error
in the rare case of a problem with the command interpreter's
executable file. Because of these implementations, the [ENOEXEC] error
is not mentioned for execlp() or execvp(), although implementations
can still give it.
Another way that some historical implementations handle shell scripts
is by recognizing the first two bytes of the file as the character
string "#!" and using the remainder of the first line of the file as
the name of the command interpreter to execute.
One potential source of confusion noted by the standard developers is
over how the contents of a process image file affect the behavior of
the exec family of functions. The following is a description of the
actions taken:
If the process image file is a valid executable (in a format that is executable and valid and having appropriate privileges) for this
system, then the system executes the file.
If the process image file has appropriate privileges and is in a format that is executable but not valid for this system (such as a
recognized binary for another architecture), then this is an error and
errno is set to [EINVAL] (see later RATIONALE on [EINVAL]).
If the process image file has appropriate privileges but is not otherwise recognized:
If this is a call to execlp() or execvp(), then they invoke a command interpreter assuming that the process image file is a shell
script.
If this is not a call to execlp() or execvp(), then an error occurs and errno is set to [ENOEXEC].
You'll note it doesn't specify how the command interpreter in 3.1 is identified.
But on Linux, it is required that shebang begin with #!
exactly. See man 2 execve
:
execve() executes the program pointed to by filename. filename must
be either a binary executable, or a script starting with a line of
the form:
#! interpreter [optional-arg]
And #
is a common enough comment character, which is why ##!
seems to cancel out the shebang without any other effects. However, the script will still be executed using sh
, so even if /foo/bar
isn't executed, it may not be what you expected. See man 3 exec
:
If the header of a file isn't recognized (the attempted execve(2)
failed with the error ENOEXEC), these functions will execute the
shell (/bin/sh) with the path of the file as its first argument. (If
this attempt fails, no further searching is done.)
I don't know of any system that accepts shebangs other than #!
, and certainly I doubt whether ##!
will be treated specially, but it's certainly possible - the standard doesn't preclude it.