Using Parameter Expansion in POSIX Shell
In POSIX shell scripts, we can use parameter expansion to reference a variable
message="hello"
printf '%s\n' "${message}"
The usefulness of this syntax is in its variations that handle variables when null/not null:
Form | Meaning |
---|---|
${var:-word} | use word if var unset/null |
${var:=word} | use word and set var to word if var unset/null |
${var:+word} | use word if var set and not null |
${var:?word} | exit with error and print word if var unset/null |
Another useful set of variations involve prefix/suffix deletion of a variable's value:
Form | Meaning |
---|---|
${var#pat} | remove the smallest prefix of var matching pattern pat |
${var##pat} | remove the largest prefix of var matching pattern pat |
${var%pat} | remove the smallest suffix of var matching pattern pat |
${var%%pat} | remove the largest suffix of var matching pattern pat |
Examples:
#!/bin/sh
#
# baz.sh
var=
printf 'var: "%s"\n' "$var"
printf 'using fallback value "%s"\n' "${var:-"some_fallback_value"}"
printf 'var: "%s"\n' "$var"
printf 'setting var to value "%s"\n' "${var:="some_value"}"
printf 'var: "%s"\n' "$var"
printf 'using "%s" because var is set\n\n' "${var:+"another_value"}"
var='/duck/duck/duck/goose/goose/goose'
printf 'original var: %s\n' "$var"
printf 'smallest prefix removed: %s\n' "${var#*/duck}"
printf 'largest prefix removed: %s\n' "${var##*/duck}"
printf 'smallest suffix removed: %s\n' "${var%/goose*}"
printf 'largest suffix removed: %s\n\n' "${var%%/goose*}"
var='/home/user/.local/bin/baz.sh'
printf 'filepath: %s\n' "$var"
printf 'dirname: %s\n' "${var%/*}"
printf 'basename: %s\n\n' "${var##*/}"
var=
printf 'this should not print: "%s"\n' "${var:?"var is unset or null"}"
Output:
$ ./baz.sh
var: ""
using fallback value "some_fallback_value"
var: ""
setting var to value "some_value"
var: "some_value"
using "another_value" because var is set
original var: /duck/duck/duck/goose/goose/goose
smallest prefix removed: /duck/duck/goose/goose/goose
largest prefix removed: /goose/goose/goose
smallest suffix removed: /duck/duck/duck/goose/goose
largest suffix removed: /duck/duck/duck
filepath: /home/user/.local/bin/baz.sh
dirname: /home/user/.local/bin
basename: baz.sh
./baz.sh: 30: var: var is unset or null
$ printf 'exit code: %s\n' $?
exit code: 2
The Open Group Base Specifications Issue 7 (2.6.2 Parameter Expansion)