Next: Here-Documents, Up: Portable Shell
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. The the Shell difference FAQ includes a small history of Posix shells, and a comparison between several of them.
Below we describe some of the members of the Bourne shell family.
To be compatible with Ash 0.2:
               foo=
               false
               $foo
               echo "Do not use it: $?"
               false
               eval 'echo "Do not use it: $?"'
          
                         cat ${FOO=`bar`}
          
          BASH_VERSION is set.  To require
Posix compatibility, run `set -o posix'.  See Bash Posix Mode, for details.
     Solaris systems have three variants: /usr/bin/ksh is `ksh88'; it is standard on Solaris 2.0 and later. /usr/xpg4/bin/sh is a Posix-compliant variant of `ksh88'; it is standard on Solaris 9 and later. /usr/dt/bin/dtksh is `ksh93'. Variants that are not standard may be parts of optional packages. There is no extra charge for these packages, but they are not part of a minimal OS install and therefore some installations may not have it.
Starting with Tru64 Version 4.0, the Korn shell /usr/bin/ksh
is also available as /usr/bin/posix/sh.  If the environment
variable BIN_SH is set to xpg4, subsidiary invocations of
the standard shell conform to Posix.
     
KSH_VERSION, except if invoked as
/bin/sh on OpenBSD, and similarly to Bash you can require
Posix compatibility by running `set -o posix'.  Unfortunately, with
pdksh 5.2.14 (the latest stable version as of February 2006)
Posix mode is buggy and causes pdksh to depart from Posix in
at least one respect:
               $ echo "`echo \"hello\"`"
          hello
          $ set -o posix
          $ echo "`echo \"hello\"`"
          "hello"
     
     The last line of output contains spurious quotes.  This is yet another
reason why portable shell code should not contain
"`...\"...\"...`" constructs (see Shell Substitutions).
     
ZSH_VERSION is set.  By default zsh is not
compatible with the Bourne shell: you must execute `emulate sh',
and for zsh versions before 3.1.6-dev-18 you must also
set NULLCMD to `:'.  See Compatibility, for details.
     The default Mac OS X sh was originally Zsh; it was changed to Bash in Mac OS X 10.2.
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 users' existing 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.