Parameter Conditionals
Standard (unconditional) parameter expansion turns the syntaxes $variable and ${variable} into their respective contents. Conditional parameter expansion uses an operator following the variable name (inside braces) to indicate conditional expansion.
The condition for expansion depends on the operator used.
Name
Condition
Operator
Example
Assign default value
unset
=
${var=default}
Assign default value
unset or NULL
:=
${var:=default}
Use default value
unset
-
${var-default}
Use default value
unset or NULL
:-
${var:-default}
Use alternate value
set
+
${var+alternate}
Use alternate value
set and non-NULL
:+
${var:+alternate}
Combining the syntax for assigning default values (${var=default and ${var:=default}) with a shell built-in such as : allows you to assign default values to one or more variables. Since the : built-in meets these requirements:
  • Does not process any arguments given
  • Performs no action and returns immediately
  • Is a built-in and as-such returns quickly
The shell built-ins true and false also meet the criteria, but false has an undesirable affect on exit status and true, while identical in functionality to :, is not guaranteed to adhere to that criterion.
If the syntax for conditionally assigning a default value has modified the contents of the variable, the assignment is done before the final expansion, meaning that the provided default value is expanded.
1
1 #!/bin/sh
2
2 : ${foo=bar} ${bar:=baz}
3
3 echo foo = "$foo"
4
4 echo bar = "$bar"
Copied!
If foo and bar are both unset when the above code runs:
1
foo = bar
2
bar = baz
Copied!
If foo=abc and bar=123 when the code runs:
1
foo = abc
2
bar = 123
Copied!
If foo and bar are both set but empty (NULL):
1
foo =
2
bar = baz
Copied!
When both are set but empty, foo remains empty because the = operator (assign default value if unset) was used while bar gets set to the default value because the := operator (assign default value if NULL or unset) was used.
Visually, it can be difficult to discern parameter expansion operators apart from each other. This can lead to the accidental removal of an expansion containing an default assignment. To avoid this danger, it is best to declare default assignments at the top of your code or start of a code block using the : built-in or similar.
After interpolation but before execution, a command such as : ${foo=bar} ${bar:=baz} may be translated into : bar baz which upon execution will give the arguments bar and baz to the : command. Hence why it is important to use a built-in such as : that ignores any arguments given.
Copy link