Bash parameter expansion is the shell’s built-in syntax for retrieving, transforming, and testing the value of a variable or other parameter. You use it every time you write $var, but its real power lies in the curly-brace forms like ${var:-default}, ${var#pattern}, and ${var^^} that let you manipulate text without calling external commands like sed or awk. This article explains the most useful forms, how they work, and common pitfalls.
Formula
The calculator above is a pace converter, not a parameter expansion example, but it shares a key idea with parameter expansion: you take raw input and transform it into a useful output. The formulas are:
- Pace (min/km) = Finish time (minutes) ÷ Distance (km)
- Speed (km/h) = Distance (km) ÷ (Finish time (minutes) ÷ 60)
Where Finish time is in minutes, Distance is in kilometers, Pace is minutes per kilometer, and Speed is kilometers per hour.
Worked Example
Using the defaults: finish time = 50 minutes, distance = 10 km.
- Pace = 50 ÷ 10 = 5.00 min/km
- Speed = 10 ÷ (50 ÷ 60) = 10 ÷ 0.8333 = 12.00 km/h
The calculator returns 5.00 min/km and 12.00 km/h.
What Is a Parameter in Bash?
A parameter is a name that holds a value. In Bash, there are three kinds:
- Variables – you assign them, e.g.,
name="Alice" - Positional parameters –
$1,$2, etc., the arguments passed to a script or function - Special parameters –
$?(exit status),$$(PID),$#(argument count), and others
Parameter expansion is the mechanism that reads their values. The simplest form is $name, but the full syntax is ${name}. The braces are optional for simple variable names but required when you want to append text directly (e.g., ${name}_suffix) or when you use any of the advanced operators.
The Core Expansion Operators
All the useful forms start with ${ and end with }. Here are the most common ones:
${var:-default}– ifvaris unset or empty, usedefault; otherwise use the value ofvar. This is the most used form.${var:=default}– same as above, but also assignsdefaulttovar.${var:?message}– ifvaris unset or empty, printmessageto stderr and exit the script (or return from a function).${var:+alternate}– ifvaris set and non-empty, usealternate; otherwise use nothing.${#var}– length of the value in characters.${var:offset:length}– substring starting atoffset(0-based) of lengthlength.
Example: echo ${greeting:-Hello} prints Hello if greeting is unset or empty, otherwise it prints the stored value.
Pattern Removal and Replacement
These forms match patterns (like filename globs) against the value:
${var#pattern}– remove the shortest match from the beginning.${var##pattern}– remove the longest match from the beginning.${var%pattern}– remove the shortest match from the end.${var%%pattern}– remove the longest match from the end.${var/pattern/replacement}– replace the first match.${var//pattern/replacement}– replace all matches.${var/#pattern/replacement}– replace only if the value starts with the pattern.${var/%pattern/replacement}– replace only if the value ends with the pattern.
These are invaluable for stripping file extensions: filename="archive.tar.gz"; echo ${filename%.tar.gz} prints archive. Or getting the basename without basename: path="/usr/bin/bash"; echo ${path##*/} prints bash.
Case Modification and Indirection
Bash 4+ adds case conversion:
${var^^}– convert all characters to uppercase.${var,,}– convert all characters to lowercase.${var^}– capitalize the first character.${var,}– lowercase the first character.
Indirection lets you use a variable’s name as a variable name: name="world"; hello="hi"; echo ${!name} prints hi because it looks up the variable whose name is the value of name.
Common Mistakes and Pitfalls
Several errors trip up both beginners and experienced scripters:
- Forgetting quotes – always quote expansions:
"${var}"to prevent word splitting and globbing. - Using
:-vs:=–:-does not change the variable;:=does. Use:-unless you really want to assign. - Pattern vs. regex – the patterns in
#,%,/are glob patterns, not regular expressions.*means “any characters”, not “zero or more of the previous”. - Off-by-one in substring –
${var:0:1}gets the first character, not the second. - Unset vs. empty –
${var:-default}treats an empty string the same as unset. If you only want to handle unset, use${var-default}(no colon).
Frequently Asked Questions
What is the difference between ${var:-default} and ${var-default}?
The colon version checks if the variable is unset or empty; the non-colon version checks only if it is unset. If var="", then ${var:-default} yields default, but ${var-default} yields an empty string.
How do I remove the last character from a string?
Use ${var%?}. The ? pattern matches exactly one character, and % removes the shortest match from the end. To remove the first character, use ${var#?}.
Can I use parameter expansion on an array?
Yes. For indexed arrays, ${arr[0]} gets the first element, ${#arr[@]} gives the count, and ${arr[@]:1:2} slices elements. For associative arrays, use the key inside the brackets.
Why does ${var^^} not work in my script?
Case modification was added in Bash 4.0. If you are on macOS, the default Bash is 3.2, which does not support it. Check your version with bash --version and consider installing a newer Bash via Homebrew, or use tr or awk as a fallback.
How do I use parameter expansion to get a default value without modifying the variable?
Use ${var:-default}. It leaves var untouched. If you want to assign the default to the variable, use ${var:=default}.
Is parameter expansion faster than using sed or awk?
Generally yes, because it is built into the shell and does not spawn a subprocess. For simple string manipulation, parameter expansion is both faster and more readable. Use external tools only for complex regex or multi-line processing.
Related
Formula used
in t | Finish time | min | 50 | 0 in d | Distance | km | 10 | 0 | 100000 out pace | Average pace | min/km | t / d | 2 out speed | Average speed | km/h | d / (t / 60) | 2
Each line is one input (in, sel, list) or one result (out: label, unit, formula, decimals). How the calculators work
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Poco C51 Airtel Prepaid Locked Variant India?
- Jenkins vs GitHub Actions: Which CI/CD Fits Your Team?
- Turn Off Backup Encryption in iTunes?
- Campus Tech Innovation Hubs: What They Are
- Shared VPS Hosting: Is It Better?
- Disk Defrag Pro: What It Does and Whether You Need It