Shellology
==========
There are several families of shells, most prominently the Bourne
family and the C shell family which are deeply incompatible. If you
want to write portable shell scripts, avoid members of the C shell
family.
Below we describe some of the members of the Bourne shell family.
Ash
`ash' is often used on GNU/Linux and BSD systems as a light-weight
Bourne-compatible shell. Ash 0.2 has some bugs that are fixed in
the 0.3.x series, but portable shell scripts should workaround
them, since version 0.2 is still shipped with many GNU/Linux
distributions.
To be compatible with Ash 0.2:
- don't use `$?' after expanding empty or unset variables:
foo=
false
$foo
echo "Don't use it: $?"
- don't use command substitution within variable expansion:
cat ${FOO=`bar`}
- beware that single builtin substitutions are not performed by
a sub shell, hence their effect applies to the current shell!
Note:Shell Substitutions, item "Command Substitution".
Bash
To detect whether you are running `bash', test if `BASH_VERSION'
is set. To disable its extensions and require POSIX
compatibility, run `set -o posix'. *Note Bash POSIX Mode:
(bash)Bash POSIX Mode, for details.
Bash 2.05 and later
Versions 2.05 and later of `bash' use a different format for the
output of the `set' builtin, designed to make evaluating this
output easier. However, this output is not compatible with earlier
versions of `bash' (or with many other shells, probably). So if
you use `bash' 2.05 or higher to execute `configure', you'll need
to use `bash' 2.05 for all other build tasks as well.
`/usr/xpg4/bin/sh' on Solaris
The POSIX-compliant Bourne shell on a Solaris system is
`/usr/xpg4/bin/sh' and is part of an extra optional package.
There is no extra charge for this package, but it is also not part
of a minimal OS install and therefore some folks may not have it.
Zsh
To detect whether you are running `zsh', test if `ZSH_VERSION' is
set. By default `zsh' is _not_ compatible with the Bourne shell:
you have to run `emulate sh' and set `NULLCMD' to `:'. Note:Compatibility, for details.
Zsh 3.0.8 is the native `/bin/sh' on Mac OS X 10.0.3.
The following discussion between Russ Allbery and Robert Lipe is
worth reading:
Russ Allbery:
The GNU assumption that `/bin/sh' is the one and only shell leads
to a permanent deadlock. Vendors don't want to break user's
existant shell scripts, and there are some corner cases in the
Bourne shell that are not completely compatible with a POSIX
shell. Thus, vendors who have taken this route will _never_
(OK..."never say never") replace the Bourne shell (as `/bin/sh')
with a POSIX shell.
Robert Lipe:
This is exactly the problem. While most (at least most System
V's) do have a Bourne shell that accepts shell functions most
vendor `/bin/sh' programs are not the POSIX shell.
So while most modern systems do have a shell _somewhere_ that
meets the POSIX standard, the challenge is to find it.