This post is a condensed but somewhat comprehensive example of Bash Parameter Expansion (also available via paste.travisflix.com). This post assumes you know the basics of what Parameter Expansion already is. If you do not, you are better off looking elsewhere.
One core functionality of Bash is to manage parameters. A parameter is an entity that stores values and is referenced by a name, a number or a special symbol.
⢠parameters referenced by a name are called variables (this also applies to arrays)
⢠parameters referenced by a number are called positional parameters and reflect the arguments given to a shell
⢠parameters referenced by a special symbol are auto-set parameters that have different special meanings and uses
Parameter expansion is the procedure to get the value from the referenced entity, like expanding a variable to print its value. On expansion time you can do very nasty things with the parameter or its value.
Arrays can be special cases for parameter expansion, every applicable description mentions arrays below.

# ______ _
# | ___ | |
# | |_/ / __ _ ___ | |__
# | ___ / _` |/ __|| '_
# | |_/ /| (_| |__ | | | |
# ____/ __,_||___/|_| |_|
# ______ _ _____ _
# | ___ | | | ___| (_)
# | |_/ /_ _ _ __ __ _ _ __ ___ ___| |_ ___ _ __ | |____ ___ __ __ _ _ __ ___ _ ___ _ __
# | __/ _` | '__/ _` | '_ ` _ / _ __/ _ '__| | __ / / '_ / _` | '_ / __| |/ _ | '_
# | | | (_| | | | (_| | | | | | | __/ || __/ | | |___> <| |_) | (_| | | | __ | (_) | | | |
# _| __,_|_| __,_|_| |_| |_|___|_____|_| ____/_/_ .__/ __,_|_| |_|___/_|___/|_| |_|
# | |
# |_|
# BASH PARAMETER EXPANSION
## https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
## https://tldp.org/LDP/abs/html/parameter-substitution.html
## Bash Hackers wiki:
## https://web.archive.org/web/20200309072646/https://wiki.bash-hackers.org/syntax/pe
## This technique allows for a variable to be assigned a value if another variable
## is either empty or is undefined. NOTE: This "other variable" can be the same or another variable.
VARIABLE1="${VARIABLE1:-value}"
${parameter:-word}
If parameter is unset or null, the expansion of word is substituted.
Otherwise, the value of parameter is substituted.
## NOTE: This form also works:
${parameter-word}
## According to the Bash documentation, for all such expansions:
##
### Omitting the colon results in a test only for a parameter that is unset. Put another way, if the colon
### is included, the operator tests for both parameters existence and that its value is not null; if the
### colon is omitted, the operator tests only for existence.
########## Examples ##########
# variable doesnt exist
$ echo "$VAR1"
$ VAR1="${VAR1:-default value}"
$ echo "$VAR1"
default value
# variable exists
$ VAR1="has value"
$ echo "$VAR1"
has value
$ VAR1="${VAR1:-default value}"
$ echo "$VAR1"
has value
# The same thing can be done by evaluating other variables, or running commands within the default value portion of the notation.
$ VAR2="has another value"
$ echo "$VAR2"
has another value
$ echo "$VAR1"
$
$ VAR1="${VAR1:-$VAR2}"
$ echo "$VAR1"
has another value
########## More Examples ##########
# You can also use a slightly different notation where its just
VARX=${VARX-<def. value>}
$ echo "${VAR1-0}"
has another value
$ echo "${VAR2-0}"
has another value
$ echo "${VAR3-0}"
0
#In the above $VAR1 & $VAR2 were already defined with the string "has another value" but $VAR3 was undefined, so the default value was used instead, 0.
########## Another Example ##########
$ VARX="${VAR3-0}"
$ echo "$VARX"
0
# Checking and assigning using := notation
# Lastly Ill mention the handy operator, :=. This will do a check and assign a value if the variable under test is empty or undefined.Lastly Ill mention the handy operator, :=. This will do a check and assign a value if the variable under test is empty or undefined.
# Example
# Notice that $VAR1 is now set. The operator := did the test and the assignment in a single operation.
$ unset VAR1
$ echo "$VAR1"
$ echo "${VAR1:=default}"
default
$ echo "$VAR1"
default
# However if the value is set prior, then it's left alone.
$ VAR1="some value"
$ echo "${VAR1:=default}"
some value
$ echo "$VAR1"
some value
## Handy Dandy Reference Table
+--------------------+----------------------------+------------------------+-----------------+
| | Parameter set and not null | Parameter set but null | Parameter unset |
+--------------------+----------------------------+------------------------+-----------------+
| ${parameter:-word} | substitute parameter | substitute word | substitute word |
+--------------------+----------------------------+------------------------+-----------------+
| ${parameter-word} | substitute parameter | substitute null | substitute word |
+--------------------+----------------------------+------------------------+-----------------+
| ${parameter:=word} | substitute parameter | assign word | assign word |
+--------------------+----------------------------+------------------------+-----------------+
| ${parameter=word} | substitute parameter | substitute null | assign word |
+--------------------+----------------------------+------------------------+-----------------+
| ${parameter:?word} | substitute parameter | error, exit | error, exit |
+--------------------+----------------------------+------------------------+-----------------+
| ${parameter?word} | substitute parameter | substitute null | error, exit |
+--------------------+----------------------------+------------------------+-----------------+
| ${parameter:+word} | substitute word | substitute null | substitute null |
+--------------------+----------------------------+------------------------+-----------------+
| ${parameter+word} | substitute word | substitute word | substitute null |
+--------------------+----------------------------+------------------------+-----------------+
| Parameter set and not null | Parameter set but null | Parameter unset | |
|---|---|---|---|
| ${parameter:-word} | substitute parameter | substitute word | substitute word |
| ${parameter-word} | substitute parameter | substitute null | substitute word |
| ${parameter:=word} | substitute parameter | assign word | assign word |
| ${parameter=word} | substitute parameter | substitute null | assign word |
| ${parameter:?word} | substitute parameter | error, exit | error, exit |
| ${parameter?word} | substitute parameter | substitute null | error, exit |
| ${parameter:+word} | substitute word | substitute null | substitute null |
| ${parameter+word} | substitute word | substitute word | substitute null |
Overview
Looking for a specific syntax you saw, without knowing the name?
- Simple usage
$PARAMETER${PARAMETER}
- Indirection
${!PARAMETER}
- Case modification
${PARAMETER^}${PARAMETER^^}${PARAMETER,}${PARAMETER,,}${PARAMETER~}${PARAMETER~~}
- Variable name expansion
${!PREFIX\*}${!PREFIX@}
- Substring removal (also for filename manipulation!)
${PARAMETER#PATTERN}${PARAMETER##PATTERN}${PARAMETER%PATTERN}${PARAMETER%%PATTERN}
- Search and replace
${PARAMETER/PATTERN/STRING}${PARAMETER//PATTERN/STRING}${PARAMETER/PATTERN}${PARAMETER//PATTERN}
- String length
${#PARAMETER}
- Substring expansion
${PARAMETER:OFFSET}${PARAMETER:OFFSET:LENGTH}
- Use a default value
${PARAMETER:-WORD}${PARAMETER-WORD}
- Assign a default value
${PARAMETER:=WORD}${PARAMETER=WORD}
- Use an alternate value
${PARAMETER:+WORD}${PARAMETER+WORD}
- Display error if null or unset
${PARAMETER:?WORD}${PARAMETER?WORD}
If you have any questions/comments regarding this article, click here or scroll down below (login isn't required to post comments and there's no waiting period).