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.
cdis verbose, so idioms such as
abs=`cd $rel && pwd`break because
absreceives the path twice.
CDPATH to the empty value is not enough for most shells.
A simple path separator is enough except for
zsh, which prefers a
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
CDPATH, since it also
behaves properly if set to the empty string).
Life wouldn't be so much fun if
zsh had the
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
Therefore, a portable solution to neutralize
Note that since
unset, you may unset
PATH_SEPARATOR as a fallback, see
Limitations of Builtins.
IFSto 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.
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
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. Its value is the line number of the beginning of the current command. Autoconf attempts to execute
configurewith a modern shell. If no such shell is available, it attempts to implement
LINENOwith 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
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. The Bourne shell considers
zsh, even in Bourne shell compatibility mode, sets
cat. If you forgot to set
NULLCMD, your script might be suspended waiting for data on its standard input.
zsh(at least 3.1.6), hence read-only. Do not use it.
configurewill detect the appropriate path separator for the build system and set the
PATH_SEPARATORoutput variable accordingly.
On DJGPP systems, the
PATH_SEPARATOR environment variable can be
set to either
; 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, 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