Bash Bash Parameter Expansion Munging during expansion


Example

Variables don't necessarily have to expand to their values - substrings can be extracted during expansion, which can be useful for extracting file extensions or parts of paths. Globbing characters keep their usual meanings, so .* refers to a literal dot, followed by any sequence of characters; it's not a regular expression.

$ v=foo-bar-baz
$ echo ${v%%-*}
foo
$ echo ${v%-*}
foo-bar
$ echo ${v##*-}
baz
$ echo ${v#*-}
bar-baz

It's also possible to expand a variable using a default value - say I want to invoke the user's editor, but if they've not set one I'd like to give them vim.

$ EDITOR=nano
$ ${EDITOR:-vim} /tmp/some_file
# opens nano
$ unset EDITOR
$ $ ${EDITOR:-vim} /tmp/some_file
# opens vim

There are two different ways of performing this expansion, which differ in whether the relevant variable is empty or unset. Using :- will use the default if the variable is either unset or empty, whilst - only uses the default if the variable is unset, but will use the variable if it is set to the empty string:

$ a="set"
$ b=""
$ unset c
$ echo ${a:-default_a} ${b:-default_b} ${c:-default_c}
set default_b default_c
$ echo ${a-default_a} ${b-default_b} ${c-default_c}
set default_c

Similar to defaults, alternatives can be given; where a default is used if a particular variable isn't available, an alternative is used if the variable is available.

$ a="set"
$ b=""
$ echo ${a:+alternative_a} ${b:+alternative_b}
alternative_a

Noting that these expansions can be nested, using alternatives becomes particularly useful when supplying arguments to command line flags;

$ output_file=/tmp/foo
$ wget ${output_file:+"-o ${output_file}"} www.stackexchange.com
# expands to wget -o /tmp/foo www.stackexchange.com
$ unset output_file
$ wget ${output_file:+"-o ${output_file}"} www.stackexchange.com
# expands to wget  www.stackexchange.com