${Parameter Expansion}
| Since: | All Linux | |
|---|---|---|
| macOS(2001 Cheetah) | ||
| Bash 2.0(1996) |
Parameter expansion (${variable...}) goes beyond simply referencing a variable's value — it also supports setting default values, extracting substrings, and performing string substitutions. Because all processing happens within the shell without spawning external commands, it is fast.
Syntax
Basic reference. ${var} makes the variable boundary explicit. While $varname treats the entire word as the variable name, writing ${var}name ensures only var is treated as the variable name.
${var}
Use a default value if var is unset or empty.
${var:-default}
Assign a default value if var is unset or empty.
${var:=default}
Print an error message and exit if var is unset or empty.
${var:?error message}
Return an alternative value only if var is set.
${var:+alternative}
String length.
${#var}
Remove shortest / longest prefix match.
${var#pattern}
${var##pattern}
Remove shortest / longest suffix match.
${var%pattern}
${var%%pattern}
Replace first / all occurrences.
${var/old/new}
${var//old/new}
Extract substring (offset:length).
${var:offset:length}
Expansion Reference
| Expansion | Description |
|---|---|
| ${var:-default} | Returns default if var is unset or empty (var is not modified). |
| ${var:=default} | Assigns default to var and returns it if var is unset or empty. |
| ${var:?msg} | Prints an error message and exits the script if var is unset or empty. |
| ${var:+alt} | Returns alt if var is set. Returns an empty string if var is unset. |
| ${#var} | Returns the length of the variable's string value. |
| ${var#pat} | Removes the shortest prefix of var that matches pat. |
| ${var##pat} | Removes the longest prefix of var that matches pat. |
| ${var%pat} | Removes the shortest suffix of var that matches pat. |
| ${var%%pat} | Removes the longest suffix of var that matches pat. |
| ${var/old/new} | Replaces the first occurrence of old with new. |
| ${var//old/new} | Replaces all occurrences of old with new. |
| ${var:offset:len} | Extracts len characters starting at position offset. |
| ${var^^} / ${var,,} | Converts all characters to uppercase / lowercase (Bash 4 and later). |
Sample Code
Use ${var:-default} to fall back to a default value when a variable is unset or empty.
sample_default.sh
name=""
echo "${name:-Guest}"
Run the following command:
bash default.sh Guest
Use ${var:=default} to assign a default value while also returning it. The leading : is a no-op command used solely to trigger the assignment.
sample_assign_default.sh
: ${config:=/etc/myapp.conf}
echo "$config"
The following example demonstrates this:
bash assign_default.sh /etc/myapp.conf
Use ${#var} to get the length of a string.
sample_strlen.sh
file="document.txt"
echo "${#file}"
Run the following command:
bash strlen.sh 12
Use ${var%.*} to strip the file extension (shortest suffix match).
file="document.txt"
echo "${file%.*}"
document
Use ${var##*/} to strip the directory portion (longest prefix match). This is a fast alternative to basename.
sample_path_parse.sh
path="/usr/local/bin/bash"
echo "${path##*/}"
echo "${path%/*}"
Run the following command:
bash path_parse.sh bash /usr/local/bin
Use ${var/old/new} to replace the first match. Use // to replace all matches.
sample_replace.sh
text="Hello World World"
echo "${text/World/Bash}"
echo "${text//World/Bash}"
Run the following command:
bash replace.sh Hello Bash World Hello Bash Bash
Use ${var:offset:length} to extract a substring.
sample_substring.sh
str="Hello, Bash!"
echo "${str:7:4}"
Run the following command:
bash substring.sh Bash
Use ${var^^} to convert to uppercase and ${var,,} to convert to lowercase (Bash 4 and later).
sample_case_convert.sh
lower="hello"
echo "${lower^^}"
upper="WORLD"
echo "${upper,,}"
Run the following command:
bash case_convert.sh HELLO world
Common Mistakes
Common Mistake 1: Confusing ${var:-default} and ${var:=default}
${var:-default} returns the default value but does not assign it to the variable. ${var:=default} both returns and assigns the default.
unset name
echo "${name:-guest}"
guest
echo "$name"
(still empty — :- does not assign)
Use := if you want the variable itself to be set to the default.
echo "${name:=guest}"
guest
echo "$name"
guest
Common Mistake 2: Mixing up # (prefix) and % (suffix) trimming direction
# trims from the beginning (prefix); % trims from the end (suffix). Using the wrong one leaves the string unchanged.
file="report.tar.gz"
echo "${file%.gz}"
report.tar
echo "${file#*.}"
tar.gz
% strips the shortest match from the end; %% strips the longest. # strips the shortest match from the beginning; ## strips the longest.
Notes
Parameter expansion is a shell built-in feature, so it does not spawn a subprocess. File path operations such as stripping extensions and extracting directory names can be performed without calling sed or awk, making loops significantly faster.
Difference between :- and -: The colon form targets variables that are unset or empty; the form without a colon targets only unset variables. In most cases you want empty strings to be replaced with the default too, so use :-.
For basic variable definition and reference, see Variable Definition and Reference.
If you find any errors or copyright issues, please contact us.