Search code examples
bashsyntaxparameter-expansion

Redundant use of :- in Bash?


I have this code inside a function:

local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
    echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
    exit 1
fi

What is the role of :- here? Isn't it redundant? To be specific, could we not write the if statement this way?

if [ "${!var}" ] && [ "${!fileVar}" ]; then

How does it help to have an empty "word" on the right side of :-?


Solution

  • Figured it out. The :- construct in indirect parameter expansion prevents the script from failing when run with set -u.

    Here is an example:

    set -u
    var=x
    [[ ${!var:-} ]] && echo This works
    [[ ${!var} ]]   && echo This should fail
    echo "This should print only when run without 'set -u'"
    

    which gives this output:

    line 6: !var: unbound variable
    

    If the same statements are run without set -u, we get:

    This should print only when run without 'set -u'
    

    However, this trick wouldn't work in case we are using direct parameter expansion. So,

    set -u
    [[ ${var:-} ]] && echo Does this work
    

    still throws the error:

    tt.sh: line 6: var: unbound variable