Node:Special Shell Variables, Next:Limitations of Builtins, Previous:Assignments, Up:Portable Shell
Some shell variables should not be used, since they can have a deep
influence on the behavior of the shell. In order to recover a sane
behavior from the shell, some variables should be unset, but
unset is not portable (see Limitations of Builtins) and a
fallback value is needed. We list these values below.
CDPATH
cd is verbose, so idioms such as
abs=`cd $rel && pwd` break because abs receives the path
twice.
Setting CDPATH to the empty value is not enough for most shells.
A simple path separator is enough except for zsh, which prefers a
leading dot:
zsh-3.1.6$ mkdir foo && (CDPATH=: cd foo) /tmp/foo zsh-3.1.6$ (CDPATH=:. cd foo) /tmp/foo zsh-3.1.6$ (CDPATH=.: cd foo) zsh-3.1.6$
(of course we could just unset CDPATH, since it also
behaves properly if set to the empty string).
Life wouldn't be so much fun if bash and zsh had the
same behavior:
bash-2.02$ mkdir foo && (CDPATH=: cd foo) bash-2.02$ (CDPATH=:. cd foo) bash-2.02$ (CDPATH=.: cd foo) /tmp/foo
Of course, even better style would be to use PATH_SEPARATOR instead
of a :.
Therefore, a portable solution to neutralize CDPATH is
CDPATH=${ZSH_VERSION+.}$PATH_SEPARATOR
Note that since zsh supports unset, you may unset
CDPATH using PATH_SEPARATOR as a fallback, see
Limitations of Builtins.
IFS
IFS to backslash. Indeed,
Bourne shells use the first character (backslash) when joining the
components in "$@" and some shells then re-interpret (!) the
backslash escapes, so you can end up with backspace and other strange
characters.
LANG
LC_ALL
LC_COLLATE
LC_CTYPE
LC_MESSAGES
LC_NUMERIC
LC_TIME
Autoconf-generated scripts normally set all these variables to
C because so much configuration code assumes the C locale and
POSIX requires that LC_ALL be set to C if the C
locale is desired. However, some older, nonstandard systems (notably
SCO) break if LC_ALL is set to C, so when running on
these systems Autoconf-generated scripts first try to unset the
variables instead.
LANGUAGE
LANGUAGE is not specified by POSIX, but it is a GNU
extension that overrides LC_ALL in some cases, so
Autoconf-generated scripts set it too.
LINENO
LINENO.
Its value is the line number of the beginning of the current command.
Autoconf attempts to execute configure with a modern shell.
If no such shell is available, it attempts to implement LINENO
with a Sed prepass that replaces the each instance of the string
$LINENO (not followed by an alphanumeric character) with the
line's number.
You should not rely on LINENO within eval, as the
behavior differs in practice. Also, the possibility of the Sed
prepass means that you should not rely on $LINENO when quoted,
when in here-documents, or when in long commands that cross line
boundaries. Subshells should be OK, though. In the following
example, lines 1, 6, and 9 are portable, but the other instances of
LINENO are not:
$ cat lineno echo 1. $LINENO cat <<EOF 3. $LINENO 4. $LINENO EOF ( echo 6. $LINENO ) eval 'echo 7. $LINENO' echo 8. '$LINENO' echo 9. $LINENO ' 10.' $LINENO $ bash-2.05 lineno 1. 1 3. 2 4. 2 6. 6 7. 1 8. $LINENO 9. 9 10. 9 $ zsh-3.0.6 lineno 1. 1 3. 2 4. 2 6. 6 7. 7 8. $LINENO 9. 9 10. 9 $ pdksh-5.2.14 lineno 1. 1 3. 2 4. 2 6. 6 7. 0 8. $LINENO 9. 9 10. 9 $ sed '=' <lineno | > sed ' > N > s,$,-, > : loop > s,^\([0-9]*\)\(.*\)[$]LINENO\([^a-zA-Z0-9_]\),\1\2\1\3, > t loop > s,-$,, > s,^[0-9]*\n,, > ' | > sh 1. 1 3. 3 4. 4 6. 6 7. 7 8. 8 9. 9 10. 10
NULLCMD
>foo, zsh executes
$NULLCMD >foo. The Bourne shell considers NULLCMD is
:, while zsh, even in Bourne shell compatibility mode,
sets NULLCMD to cat. If you forgot to set NULLCMD,
your script might be suspended waiting for data on its standard input.
status
$? for zsh (at least 3.1.6),
hence read-only. Do not use it.
PATH_SEPARATOR
configure will detect the appropriate path
separator for the build system and set the PATH_SEPARATOR output
variable accordingly.
On DJGPP systems, the PATH_SEPARATOR environment variable can be
set to either : or ; to control the path separator
bash uses to set up certain environment variables (such as
PATH). Since this only works inside bash, you want
configure to detect the regular DOS path separator
(;), so it can be safely substituted in files that may not support
; as path separator. So it is recommended to either unset this
variable or set it to ;.
RANDOM
RANDOM, a variable that returns a different
integer when used. Most of the time, its value does not change when it
is not used, but on IRIX 6.5 the value changes all the time. This
can be observed by using set.