Test if a variable is set in bash when using “set -o nounset”

前端 未结 6 1691
北海茫月
北海茫月 2020-12-07 13:28

The following code exits with a unbound variable error. How to fix this, while still using the set -o nounset option?

#!/bin/bash

set -o nounse         


        
相关标签:
6条回答
  • 2020-12-07 13:31

    How about a oneliner?

    [ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"
    

    -z checks both for empty or unset variable

    0 讨论(0)
  • 2020-12-07 13:36
    #!/bin/bash
    
    set -o nounset
    
    
    VALUE=${WHATEVER:-}
    
    if [ ! -z ${VALUE} ];
     then echo "yo"
    fi
    
    echo "whatever"
    

    In this case, VALUE ends up being an empty string if WHATEVER is not set. We're using the {parameter:-word} expansion, which you can look up in man bash under "Parameter Expansion".

    0 讨论(0)
  • 2020-12-07 13:38

    While this isn't exactly the use case asked for above, I've found that if you want to use nounset (or -u) the default behavior is the one you want: to exit nonzero with a descriptive message.

    It took me long enough to realize this that I figured it was worth posting as a solution.

    If all you want is to echo something else when exiting, or do some cleanup, you can use a trap.

    The :- operator is probably what you want otherwise.

    0 讨论(0)
  • 2020-12-07 13:40

    You need to quote the variables if you want to get the result you expect:

    check() {
        if [ -n "${WHATEVER-}" ]
        then
            echo 'not empty'
        elif [ "${WHATEVER+defined}" = defined ]
        then
            echo 'empty but defined'
        else
            echo 'unset'
        fi
    }
    

    Test:

    $ unset WHATEVER
    $ check
    unset
    $ WHATEVER=
    $ check
    empty but defined
    $ WHATEVER='   '
    $ check
    not empty
    
    0 讨论(0)
  • 2020-12-07 13:40

    You can use

    if [[ ${WHATEVER:+$WHATEVER} ]]; then
    

    but

    if [[ "${WHATEVER:+isset}" == "isset" ]]; then
    

    might be more readable.

    0 讨论(0)
  • 2020-12-07 13:43

    Assumptions:

    $ echo $SHELL
    /bin/bash
    $ /bin/bash --version | head -1
    GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
    $ set -o nounset
    

    If you want a non-interactive script to print an error and exit if a variable is null or not set:

    $ [[ "${HOME:?}" ]]
    
    $ [[ "${IAMUNBOUND:?}" ]]
    bash: IAMUNBOUND: parameter null or not set
    
    $ IAMNULL=""
    $ [[ "${IAMNULL:?}" ]]
    bash: IAMNULL: parameter null or not set
    

    If you don't want the script to exit:

    $ [[ "${HOME:-}" ]] || echo "Parameter null or not set."
    
    $ [[ "${IAMUNBOUND:-}" ]] || echo "Parameter null or not set."
    Parameter null or not set.
    
    $ IAMNULL=""
    $ [[ "${IAMUNNULL:-}" ]] || echo "Parameter null or not set."
    Parameter null or not set.
    

    You can even use [ and ] instead of [[ and ]] above, but the latter is preferable in Bash.

    Note what the colon does above. From the docs:

    Put another way, if the colon is included, the operator tests for both parameter’s existence and that its value is not null; if the colon is omitted, the operator tests only for existence.

    There is apparently no need for -n or -z.

    In summary, I may typically just use [[ "${VAR:?}" ]]. Per the examples, this prints an error and exits if a variable is null or not set.

    0 讨论(0)
提交回复
热议问题