Munging during expansion
suggest changeVariables 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