Differences between revisions 2 and 3
Revision 2 as of 2015-01-05 18:10:36
Size: 1984
Editor: JarnoSuni
Comment:
Revision 3 as of 2015-01-06 09:48:21
Size: 2167
Editor: JarnoSuni
Comment:
Deletions are marked like this. Additions are marked like this.
Line 9: Line 9:
 * Just use [ "$#" -gt 0 ] instead of [ "$1" ] and it works no matter what the setting is.  * You can use
 {{{
[ "$#" -gt 0 ]
 }}}
 instead of
 {{{
 [ "$1" ]
 }}}
 and it works no matter what the setting is. Just note that "$1" may be empty sting. After that the latter test can be used to test if "$1" is non-empty string (i.e. not "" in command line).

What are the advantages and disadvantages of using set -u (or set -o nounset)?

Bash (like all other Bourne shell derivatives) has a feature activated by the command set -u (or set -o nounset). When this feature is in effect, any command which attempts to expand an unset variable will cause a fatal error (the shell immediately exits, unless it is interactive).

This feature is rather controversial, and has many extremely vocal advocates and opponents. It is designed to catch typos (misspelled variable names). However, it also triggers on many false positives, unless scripts are rewritten explicitly with set -u in mind. It is not always safe to add to the top of a script.

Positives

Advocates of set -u say the following:

  • You can use
    [ "$#" -gt 0 ]
    instead of
     [ "$1" ]
    and it works no matter what the setting is. Just note that "$1" may be empty sting. After that the latter test can be used to test if "$1" is non-empty string (i.e. not "" in command line).

Negatives

Opponents of set -u say the following:

  • Turning this feature on breaks many scripts that do not even contain errors. There are some extremely common shell programming idioms that rely on the expansion of positional parameters (which may not be set). For example:

    while [ "$1" ]; do
      case $1 in
        -h|-?) usage;;
        --) shift; break;;
        -*) usage "Invalid option $1";;
      esac
    done
  • A forced termination is a ridiculous way to handle a condition that isn't even always a real error. Why not simply print an error and move on, so you can catch all of your misspelled variables in a single run?

Rewriting scripts to deal with it

If you want to use set -u, you may have to rewrite portions of your script, to avoid having it trigger on false positives. For the most part, this involves identifying which parameter expansions should be "ignored", and protecting them with a construct such as this:

while [ "$1" ]; do         # Triggers fatal error with -u

while [ ${1+"$1"} ]; do    # Avoids fatal error with -u

BashFAQ/112 (last edited 2019-07-25 14:15:58 by intranet)