iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Two Bash parameter-expansion details can make a short expression behave unlike it looks: a space changes a negative substring offset from the :- default operator, and an unquoted ampersand can stand for the matched text during pattern replacement. Here is how to read and review both forms, with the relevant Bash option and operand rules.
Why does ${value: -2} differ from ${value:-2}?
They use different parameter-expansion operators. In ${value: -2}, the colon introduces substring expansion and the negative offset counts backward from the end of the value. In ${value:-2}, :- is the default-value operator: it expands to value if that parameter is set and non-null, or to the literal 2 otherwise.
Keep the space before a negative offset so the expression is clearly parsed as substring syntax rather than the :- operator:
value=abcdef
printf '<%s>n' "${value: -2}"
Output:
<ef>
For scalar substring expansion, a negative offset is measured in characters from the end of the value. A negative length has a different meaning: it specifies an endpoint offset measured from the end, and Bash returns the characters between the starting offset and that endpoint. See the GNU Bash Reference Manual’s substring expansion rules.
#1 Best Overall
- Used Book in Good Condition
Do not transfer the scalar rule to arrays or positional parameters
Negative offsets are supported for scalar substring expansion, but a negative length is an expansion error when the operand is positional parameters or an indexed array. A review should therefore check both the sign of the value and what the expansion operates on; syntax that is valid for a scalar is not automatically valid for those other operands.
Why can an ampersand become the matched text?
In pattern substitution, ${parameter/pattern/string} replaces only the first match, while ${parameter//pattern/string} replaces every match. The pattern uses Bash shell-pattern syntax, not regular-expression syntax.
In Bash 5.3, when the patsub_replacement shell option is enabled, each unquoted & in the replacement string is replaced by the text matched by the pattern. For example:
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →shopt -s patsub_replacement
value=abc123xyz
printf '%sn' "${value/[0-9]*/&!}"
The pattern matches 123xyz, so the replacement expands to that matched text followed by !; the result is abc123xyz!. To make the ampersand literal, quote the replacement portion:
printf '%sn' "${value/[0-9]*/'&'!}"
With the option enabled, the quoted ampersand remains literal, producing abc&!. This quoting control applies to the replacement portion; double-quoting the overall expansion does not by itself make an unquoted ampersand in that portion literal.
Check the option instead of assuming its state
Use shopt -q patsub_replacement to test whether the option is enabled in the current shell, or inspect shopt patsub_replacement. With the option disabled, an unquoted ampersand in the replacement string is ordinary text rather than a match reference. Avoid assuming a universal default across Bash versions and distribution builds: the GNU Bash manual index identifies the current reference manual as Bash 5.3, with its edition updated on 18 May 2025, but local shell configuration and builds can affect the state you encounter.
Quick Recap
Best Value
Rank #4
A quick code-review checklist
- For substring syntax, verify whether the expression uses a negative offset or a negative length, and keep whitespace before a negative offset such as
${value: -2}. - Check whether the operand is a scalar, positional parameters, or an indexed array before accepting a negative length.
- Confirm whether substitution should replace one match (
/) or all matches (//); the pattern is a shell pattern. - When a replacement contains
&, checkpatsub_replacementin the relevant shell and quote the replacement ampersand if it must stay literal.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.

