Bash parameter expansion
Parameter expansion is the ${...} syntax that lets Bash transform a variable’s
value as it is substituted into a command — without calling external tools like
sed, cut or tr. It covers default values, substring slicing, pattern-based
trimming, search-and-replace, case changes, length and indirection. This page is
a searchable, offline reference: filter by keyword or group, read a working
example for each form, and click any pattern to copy it.
How it works
Every form is interpreted by the shell itself before the command runs. The core families are:
- Default / alternate —
${var:-w},${var:=w},${var:+w},${var:?w}decide what to substitute when a variable is unset or null. A leading colon also treats an empty value as “null”; without it, only fully unset variables qualify. - Substring —
${var:offset:length}slices by character index (0-based); negative offsets count from the end. - Removal —
#/##strip a prefix and%/%%strip a suffix using glob patterns; the doubled form is greedy (longest match). - Replacement —
${var/pat/str}(first) and${var//pat/str}(all), with/#and/%anchoring to the start or end. - Case —
^/^^uppercase and,/,,lowercase (Bash 4+). - Length / indirection —
${#var}returns length;${!var}dereferences.
Tips and examples
Combine forms to build robust scripts. For example, to get a filename without its directory or extension:
path=/var/log/app.log
base=${path##*/} # app.log (strip longest leading dir)
name=${base%.*} # app (strip trailing extension)
Use the assign-default form to fill a config value once and reuse it:
: "${PORT:=8080}" # PORT is now 8080 if it was unset
echo "Listening on ${PORT}"
Note that these operate on plain text, not on the filesystem — the patterns in
#, % and / are shell globs, not regular expressions, so * matches any
string and ? matches a single character.