While I was playing around in my shell investigating the answer to this question, I noticed that, even though /bin/sh
was pointing to /bin/bash
on my system, the two commands behave differently. First of all, the output of
ls -lh /bin/sh
is:
lrwxrwxrwx 1 root root 4 Apr 22 2013 /bin/sh -> bash*
However, invoking the following command through /bin/sh
:
/bin/sh -c "script.sh 2> >( grep -v FILTER 2>&1 )"
returns this error:
/bin/sh: -c: line 0: syntax error near unexpected token '>'
/bin/sh: -c: line 0: 'script.sh 2> >( grep -v FILTER 2>&1 )'
While running the same command through /bin/bash
:
/bin/bash -c "script.sh 2> >( grep -v FILTER 2>&1 )"
executes successfully, here is the output:
This should be on stderr
For reference, here is the contents of script.sh
:
#!/bin/sh
echo "FILTER: This should be filtered out" 1>&2
echo "This should be on stderr" 1>&2
echo "FILTER: This should be filtered out" 1>&2
Why do the two invocations behave differently?
bash
looks at the value of $argv[0]
(bash is implemented in C) to determine how it was invoked.
Its behavior when invoked as sh
is documented in the manual:
If Bash is invoked with the name
sh
, it tries to mimic the startup behavior of historical versions ofsh
as closely as possible, while conforming to the POSIX standard as well.When invoked as an interactive login shell, or as a non-interactive shell with the
-login
option, it first attempts to read and execute commands from/etc/profile
and~/.profile
, in that order. The--noprofile
option may be used to inhibit this behavior. When invoked as an interactive shell with the namesh
, Bash looks for the variableENV
, expands its value if it is defined, and uses the expanded value as the name of a file to read and execute. Since a shell invoked assh
does not attempt to read and execute commands from any other startup files, the--rcfile
option has no effect. A non-interactive shell invoked with the namesh
does not attempt to read any other startup files.When invoked as
sh
, Bash enters POSIX mode after the startup files are read
There's a long list (currently 46 items) of things that change when bash
is in POSIX mode, documented here.
(POSIX mode is probably useful mostly as a way to test scripts for portability to non-bash
shells.)
Incidentally, programs that change their behavior depending on the name under which they were invoked are fairly common. Some versions of grep
, fgrep
, and egrep
are implemented as a single executable (though GNU grep
doesn't do this). view
is typically a symbolic link to vi
or vim
; invoking it as view
causes to open in read-only mode. The Busybox system includes a number of individual commands that are all symlinks to the master busybox
executable.