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.
As a general rule, shell variable names containing a lower-case letter
are safe; you can define and use these variables without worrying about
their effect on the underlying system, and without worrying about
whether the shell changes them unexpectedly. (The exception is the
status, as described below.)
Here is a list of names that are known to cause trouble. This list is
not exhaustive, but you should be safe if you avoid the name
status and names containing only upper-case letters and
xpg4, subsidiary invocations of the standard shell conform to Posix. Autoconf-generated scripts export this variable when they start up.
cdwith a relative file name that did not start with ‘./’ or ‘../’. Posix 1003.1-2001 says that if a nonempty directory name from CDPATH is used successfully,
cdprints the resulting absolute file name. Unfortunately this output can break idioms like ‘abs=`cd src && pwd`’ because
absreceives the name twice. Also, many shells do not conform to this part of Posix; for example, zsh prints the result only if a directory name other than . was chosen from CDPATH.
In practice the shells that have this problem also support unset, so you can work around the problem as follows:
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
You can also avoid output by ensuring that your directory name is absolute or anchored at ‘./’, as in ‘abs=`cd ./src && pwd`’.
Autoconf-generated scripts automatically unset CDPATH if
possible, so you need not worry about this problem in those scripts.
(unset ENV) >/dev/null 2>&1 && unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ '
Don't set the first character of
IFS to backslash. Indeed,
Bourne shells use the first character (backslash) when joining the
components in ‘"$@"’ and some shells then reinterpret (!) the
backslash escapes, so you can end up with backspace and other strange
The proper value for
IFS (in regular code, not when performing
splits) is ‘<SPC><TAB><RET>’. The first character is
especially important, as it is used to join the arguments in ‘$*’;
however, note that traditional shells, but also bash-2.04, fail to adhere
to this and join with a space anyway.
LINENO. Its value is the line number of the beginning of the current command. Autoconf attempts to execute configure with a shell that supports
LINENO. If no such shell is available, it attempts to implement
LINENOwith a Sed prepass that replaces 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,$,-, > t loop > :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
RANDOM, a variable that returns a different integer each time it is 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. It is common practice to use
$RANDOMas part of a file name, but code shouldn't rely on
$RANDOMexpanding to a nonempty string.
zsh(at least 3.1.6), hence read-only. Do not use it.