(autoconf.info)Special Shell Variables

Next: Shell Functions Prev: Slashes Up: Portable Shell

10.10 Special Shell Variables

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 (Note: Limitations of Builtins) and a fallback value is

   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 shell variable `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 underscores.

     Many shells reserve `$_' for various purposes, e.g., the name of
     the last command executed.

     In Tru64, if `BIN_SH' is set to `xpg4', subsidiary invocations of
     the standard shell conform to Posix.

     When this variable is set it specifies a list of directories to
     search when invoking `cd' with 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, `cd'
     prints the resulting absolute file name.  Unfortunately this
     output can break idioms like `abs=`cd src && pwd`' because `abs'
     receives 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

     In the MKS shell, case statements and file name generation are
     case-insensitive unless `DUALCASE' is nonzero.  Autoconf-generated
     scripts export this variable when they start up.

     These variables should not matter for shell scripts, since they are
     supposed to affect only interactive shells.  However, at least one
     shell (the pre-3.0 UWIN Korn shell) gets confused about whether it
     is interactive, which means that (for example) a `PS1' with a side
     effect can unexpectedly modify `$?'.  To work around this bug,
     Autoconf-generated scripts do something like this:

          (unset ENV) >/dev/null 2>&1 && unset ENV MAIL MAILPATH
          PS1='$ '
          PS2='> '
          PS4='+ '

     The Korn shell uses `FPATH' to find shell functions, so avoid
     `FPATH' in portable scripts.  `FPATH' is consulted after `PATH',
     but you still need to be wary of tests that use `PATH' to find
     whether a command exists, since they might report the wrong result
     if `FPATH' is also set.

     Long ago, shell scripts inherited `IFS' from the environment, but
     this caused many problems so modern shells ignore any environment
     settings for `IFS'.

     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 characters.

     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.

     Autoconf-generated scripts normally set all these variables to `C'
     because so much configuration code assumes the C locale and Posix
     requires that locale environment variables be set to `C' if the C
     locale is desired.  However, some older, nonstandard systems
     (notably SCO) break if locale environment variables are set to
     `C', so when running on these systems Autoconf-generated scripts
     unset the variables instead.

     `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.

     These locale environment variables are GNU extensions.  They are
     treated like their Posix brethren (`LC_COLLATE', etc.) as
     described above.

     Most modern shells provide the current line number in `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 `LINENO' with 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
          ( 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

     When executing the command `>foo', `zsh' executes `$NULLCMD >foo'
     unless it is operating in Bourne shell compatibility mode and the
     `zsh' version is newer than 3.1.6-dev-18.  If you are using an
     older `zsh' and forget to set `NULLCMD', your script might be
     suspended waiting for data on its standard input.

     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').  You can
     set this variable to `;' if you want `configure' to use `;' as a
     separator; this might be useful if you plan to use non-Posix
     shells to execute files.  Note: File System Conventions, for
     more information about `PATH_SEPARATOR'.

     Posix 1003.1-2001 requires that `cd' and `pwd' must update the
     `PWD' environment variable to point to the logical name of the
     current directory, but traditional shells do not support this.
     This can cause confusion if one shell instance maintains `PWD' but
     a subsidiary and different shell does not know about `PWD' and
     executes `cd'; in this case `PWD' points to the wrong directory.
     Use ``pwd`' rather than `$PWD'.

     Many shells provide `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 `$RANDOM' as part of a file name, but code
     shouldn't rely on `$RANDOM' expanding to a nonempty string.

     This variable is an alias to `$?' for `zsh' (at least 3.1.6),
     hence read-only.  Do not use it.

automatically generated by info2www