What does a minus sign inside of dollar brackets of a shell script mean?

Solution 1:

According to the section on "Parameter Expansion" in the bash man page, this means "use the default value if the parameter is unset." So for example,

${PID-/run/unicorn.pid}

equals $PID if $PID is set, otherwise /run/unicorn.pid.

Solution 2:

It should be emphasized that this means an unset variable. Not an empty one.
And to put to comparison with :-, which will use default value (the one after minus sign) if variable is unset or null (as in empty string).
Minus without a colon is not seen as often (at least not by me) and has more specific use than :- It's not even mentioned on GNU manual and not in my man bash, but it's described for example on tldp.

In cases where you need to substitute default value, when the variable doesn't hold sensible value. The later is more suitable.

PID=${PID-/run/unicorn.pid}
PID might have been used and later emptied using PID="" in the script. This association will than fail and PID will stay an empty string ""

PID=${PID:-/run/unicorn.pid}
PID will become "/run/unicorn.pid" if it was unset, but even if it was null ("") before.

A construct without a default value ${previous-} is debated to be a safe-guard against someone having set -u

set -u|nounset

Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error when performing parameter expansion. An error message will be written to the standard error, and a non-interactive shell will exit.
https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html

set -u
[ "${previous}" ] || echo "This will fail"
[ "${previous-}" ] || echo "This works"