This behavior is actually specified by POSIX standard, which all Bourne-like shells should support to claim themselves portable.
sh -c [-abCefhimnuvx] [-o option]... [+abCefhimnuvx] [+o option]...
command_string [command_name [argument...]]
See the command_string
parameter ? Now let's look at -c
flag description:
-c
Read commands from the command_string operand. Set the value of special parameter 0 (see Special Parameters) from the value of the command_name operand and the positional parameters ($1, $2, and so on) in sequence from the remaining argument operands. No commands shall be read from the standard input.
In other words, where in normal shell script $0
(which is usually shell name in interactive mode or script name when you run a script) would be set by the shell itself, with -c
you have to specify it yourself. Thus,
sh -c 'echo Hi, I am $0 , my first positional parameter is $1' foobar 5
would set the process name to sh
foobar.
Just in case you're wondering what $0
is, it's also covered in "Special Parameters" section of Shell Command Language Specifications:
0
(Zero.) Expands to the name of the shell or shell script.