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
.