[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
11.1 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. 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.
- 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 work around 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,
or at the start of an
eval
:foo= false $foo echo "Do not use it: $?" false eval 'echo "Do not use it: $?"'
- -
don't use command substitution within variable expansion:
cat ${FOO=`bar`}
- - beware that single builtin substitutions are not performed by a subshell, hence their effect applies to the current shell! See section Shell Substitutions, item “Command Substitution”.
- -
don't use ‘$?’ after expanding empty or unset variables,
or at the start of an
- Bash
-
To detect whether you are running Bash, test whether
BASH_VERSION
is set. To require Posix compatibility, run ‘set -o posix’. See (bash)Bash POSIX Mode section `Bash Posix Mode' in The GNU Bash Reference Manual, 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 its 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 executeconfigure
, you'll need to use Bash 2.05 for all other build tasks as well. - Ksh
-
The Korn shell is compatible with the Bourne family and it mostly conforms to Posix. It has two major variants commonly called ‘ksh88’ and ‘ksh93’, named after the years of initial release. It is usually called
ksh
, but is calledsh
on some hosts if you set your path appropriately.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 variableBIN_SH
is set toxpg4
, subsidiary invocations of the standard shell conform to Posix. - Pdksh
-
A public-domain clone of the Korn shell called
pdksh
is widely available: it has most of the ‘ksh88’ features along with a few of its own. It usually setsKSH_VERSION
, except if invoked as/bin/sh
on OpenBSD, and similarly to Bash you can require Posix compatibility by running ‘set -o posix’. Unfortunately, withpdksh
5.2.14 (the latest stable version as of January 2007) Posix mode is buggy and causespdksh
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 section Shell Substitutions). - Zsh
-
To detect whether you are running
zsh
, test whetherZSH_VERSION
is set. By defaultzsh
is not compatible with the Bourne shell: you must execute ‘emulate sh’, and forzsh
versions before 3.1.6-dev-18 you must also setNULLCMD
to ‘:’. See (zsh)Compatibility section `Compatibility' in The Z Shell Manual, for details.The default Mac OS X
sh
was originally Zsh; it was changed to Bash in Mac OS X 10.2.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |