The "invoked as" refers to whatever it is that the process starting Bash puts in its "zeroth" command line argument, argv[0]
.
When a program is started with the exec*()
syscalls, they don't really get to know the name of the binary file containing the program, but instead the calling process is free to put whatever it wants in there. Usually, of course, the name is taken from the filesystem, so if you run /bin/sh
, that's what gets put there. And if /bin/sh
is Bash, it doesn't have to be a symlink, it could be a hard link or just another copy of the shell program.
As an example of setting the "program name", Bash's exec
command can set the zeroth argument with the -a
option. (We could do the same with Perl, or directly with C, etc.)
Here, myname
is a simple C program that just prints its zeroth argument, the name it sees itself:
$ ./myname
I am ./myname
$ (exec -a something ./myname )
I am something
$ mv ./myname somename
$ ln -s somename othername
$ ./somename
I am ./somename
$ ./othername
I am ./othername
Source:
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("I am %s\n", argv[0]);
return 0;
}
But, to answer the numbered questions...
(1 & 4) running sh somescript
will run whatever sh
is on your PATH
, probably /bin/sh
but possibly something like /usr/xpg4/bin/sh
.
- If it's Bash, it runs in POSIX mode, since it sees the name
sh
.
- If it is the Z shell or the Korn shell, it likewise sees the name
sh
, but it runs in "SH compatible" mode, which is aimed at being Bourne shell compatible and is subtly different to the full POSIX conformant mode in both of those shells.
- It could be the Almquist shell, an actual Bourne shell, or something else, of course.
(2 & 5) Running bash somescript
will run in regular Bash mode (again, it of course depends on what bash
in your PATH
is.)
(3) Here, the name of the script is given directly to the system call in place of the program file. The kernel reads the hashbang line and uses it to run the script.
(6) This is the complex one. It is similar to (3), but the system call for starting the program fails (ENOEXEC (Exec format error)
), since there is no hashbang line. What happens next depends from whether the the shell that you are running is itself in POSIX mode. POSIX requires that a POSIX-conformant shell behave in a specific fashion in response to ENOEXEC
. However, there is some leeway in "a command equivalent to having a shell invoked" which means that different shells do different things.
- The Bourne Again shell re-runs itself in the same mode with the name of the script as its first command-line argument. In its POSIX-conformant mode, it is of course running itself in its POSIX-conformant mode, thus obeying the POSIX requirement to invoke a POSIX-conformant shell.
- The Z shell, Almquist shell, and Korn shell run
/bin/sh
with the name of the script inserted before the other arguments as its first command-line argument. The Z shell, Almquist shell, and Korn shell are (attempting) to invoke a POSIX-conformant shell by dint of assuming that the /bin/sh
program is one.