|
22.2.7 $
When using shell variables in your portable scripts, you need to write
them in a somewhat stylised fashion to maximise the number of
shell implementations that will interpret your code as expected:
-
Convenient though it is, the POSIX `$(command parameters)'
syntax for command substitution is not remotely portable. Despite it
being more difficult to nest, you must use
``command parameters`' instead.
-
The most portable way to set a default value for a shell variable is:
|
$ echo ${no_such_var-"default value"}
default value
|
If there is any whitespace in the default value, as there is here, you
must be careful to quote the entire value, since some shells will raise
an error:
|
$ echo ${no_such_var-default value}
sh: bad substitution
|
-
The
unset command is not available in many of the degenerate
Bourne shell implementations. Generally, it is not too difficult to get
by without it, but following the logic that led to the shell script in
(), it would be trivial to extend the test case for
confirming a shell's suitability to include a check for unset .
Although it has not been put to the test, the theory is that all the
interesting machines in use today have some shell that supports
unset .
-
Be religious about double quoting variable expansions. Using
`"$foo"' will avoid trouble with unexpected spaces in filenames,
and compression of all whitespace to a single space in unquoted variable
expansions.
-
To avoid accidental interpretation of variable expansions as command
options you can use the following technique:
|
$ foo=-n
$ echo $foo
$ echo x"$foo" | sed -e 's/^x//'
-n
|
-
If it is set,
IFS splits words on whitespace by default. If you
change it, be sure to put it back when you're done, or the shell may
behave very strangely from that point. For example, when you need to
examine each element of `$PATH' in turn:
|
# The whitespace at the end of the following line is a space
# followed by literal tab and newline characters.
save_IFS="${IFS=
}"; IFS=":"
set dummy $PATH
IFS="$save_IFS"
shift
|
Alternatively, you can take advantage of the fact that command
substitutions occur in a separate subshell, and do not corrupt the
environment of the calling shell:
|
set dummy `IFS=:; echo $PATH`
shift
|
Strictly speaking, the `dummy' argument is required to stop the
set command from interpreting the first word of the expanded
backquote expression as a command option.
Realistically, no one is going to have `-x', for example, as the
first element of their `PATH' variable, so the `dummy' could
be omitted -- as I did earlier in the script in ().
-
Some shells expand `$@' to the empty string, even when there are
no actual parameters (`$#' is 0). If you need to replicate the
parameters that were passed to the executing script, when feeding the
script to a more suitable interpreter for example, you must use the
following:
Similarly, although all known shells do correctly use `$@' as the
default argument to a for command, you must write it like this:
When you rely on implicit `$@' like this, it is important to write
the do keyword on a separate line. Some degenerate shells
can not parse the following:
|