How-To: Bash Parameter Expansion and Default Values

2 minute read

Bash is a sh-compatible command language interpreter that executes commands read from the standard input or from a file.

There is much more to bash than running a sequence of commands, one of the features bundled with bash is parameter expansion.

Any shell user has most likely used shell variables, be it $1 or $myvar, to save values… but there is more to it. This tutorial will cover a subset of shell parameter expansion that can become really handy and save you a lot of time.

Parameter expansion is introduced by the dollar $ character followed by the parameter name optionally enclosed in curly brackets to protect the variable to be expanded from characters following it and which could be interpreted as the variable name.

So far, I guess everybody is aware of this. There is many common operation that you might have come across when creating shell scripts, like:

  • assigning a default value to a variable
  • string substitution
  • substring
  • Removing prefixes/sufixes
  • Case modification
  • …..

Guess what, this can be done using builtin shell functionalities, no need to rely on external programs like expr, sed or even basename and dirname for path manipulation…..

In this article, we will see how we can handle default value assignment.

Default Values

Default value handling is done by parameter of the form: ${parameter:[-=?+]word} such as:

  • ${parameter:-word} to use a default value
  • ${parameter:=word} to assign a default value
  • ${parameter:?word} to display an error if unset or null
  • ${parameter:+word} to use an alternate value

Use a default value

To use a default value, we will use the form ${parameter:-word}. If parameter is null or unset it will expand to word, otherwise it will expand to parameter, e.g it will be similar to ${parameter}.

The script below shows a use case where if the $HOME is not set, it will default to /home/${USER}.

#!/bin/bash
unset HOME
echo ${HOME:-/home/${USER}}
echo $HOME
echo "== END of script =="

Will output:

chantra@testing:~$ ./bash-expansion.sh
/home/chantra

== END of script ==

Assign a default value

As you could see in the previous example, HOME was not set after the expansion. In order to also set the parameter we can use ${parameter:=word} type of expansion.

Let’s modify the previous script to:

#!/bin/bash
unset HOME
echo ${HOME:=/home/${USER}}
echo $HOME
echo "== END of script =="

The output is now:

chantra@testing:~$ ./bash-expansion.sh
/home/chantra
/home/chantra
== END of script ==

As you can see, HOME now has the value of /home/${USER}.

Display Error if Null or Unset

Sometimes, you might want to check if a value is set and exit if not. The form ${parameter:?word} allows you to do that in a pretty easy way:

#!/bin/bash
unset HOME
echo ${HOME:?is not set}
echo "== END of script =="

will return 1 and output:

chantra@testing:~$ ./dftval-dsplerror.sh
./dftval-dsplerror.sh: line 3: HOME: is not set

Using an Alternate Value

The form ${parameter:+word} will expand word only if parameter is set and not null. For instance:

#!/bin/bash
echo ${HOME:+HOME is set}
echo "== END of script =="

will output:

chantra@testing:~$ ./alt.sh
HOME is set
== END of script ==

That is it on how to handle default values with bash parameter expansion. I will cover other bash parameter expansion features in coming articles.

Tks.