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: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
, andegrep
are implemented as a single executable (though GNUgrep
doesn't do this).view
is typically a symbolic link tovi
orvim
; invoking it asview
causes to open in read-only mode. The Busybox system includes a number of individual commands that are all symlinks to the masterbusybox
executable.Invoking bash as
sh
causes it to enter posix mode after reading the startup files it would normally read (as opposed to the startup files a POSIX sh would read.) Bash has many different invocation modes. You can find out about these modes from theINVOCATION
section of the manual. Here is some detail about the POSIX mode.POSIX mode
This mode means bash will try, in various degrees, to conform to POSIX expectations. As explained here, bash has a few different invocations for this mode, with slightly different implications:
sh
: Bash enters POSIX mode after reading startup files.bash --posix
: Bash enters POSIX mode before reading startup files.set -o posix
: Bash switches to POSIX mode.POSIXLY_CORRECT
: If this variable is in the environment when bash starts, the shell enters posix mode before reading the startup files, likebash --posix
. If it is set while bash is running, likeset -o posix
.From the Bash Reference Manual:
Because the
bash
binary checks how it was invoked (viaargv[0]
) and enters a compatibility mode if it's being run assh
.