Przejdลบ do treล›ci

๐Ÿงฉ Advanced Shell Expansions

๐Ÿง  Overview

Shell expansions are the heart of the shell execution model. Before any command runs, the shell rewrites the input through a deterministic but complex sequence of transformations: parameter expansion, command substitution, arithmetic expansion, pathname expansion, word splitting, and quote removal. Most subtle bugs, security issues, and unexpected behaviors originate here.


๐ŸŽ“ Who this is for

  • Engineers writing productionโ€‘grade shell scripts.
  • DevOps/SRE dealing with CI/CD, containers, and automation.
  • Anyone debugging quoting, variable behavior, or unexpected command output.
  • People who want to understand the shell as a transformation engine.

๐Ÿงฉ Internals / Mechanics

๐Ÿงฉ The expansion order (POSIX)

Shell expansions occur in this strict order:

  1. Brace expansion (Bash only)
  2. Tilde expansion
  3. Parameter expansion ($VAR, ${VAR}, ${VAR:-default})
  4. Command substitution ($(...), `...`)
  5. Arithmetic expansion ($(( ... )))
  6. Word splitting
  7. Pathname expansion (globbing: *, ?, [...])
  8. Quote removal

Understanding this order is essential for predicting behavior.

๐Ÿงฉ Parameter expansion

Examples:

1
2
3
4
${VAR:-default}   # default if unset or empty
${VAR:=default}   # assign default if unset or empty
${VAR:+alt}       # alt if VAR is set
${VAR:?error}     # error if unset or empty

๐Ÿงฉ Command substitution

Runs in a subshell:

1
files=$(ls)

Always strips trailing newlines.

๐Ÿงฉ Arithmetic expansion

1
i=$((i+1))

Uses Cโ€‘style integer arithmetic.

๐Ÿงฉ Word splitting

Controlled by $IFS. Happens after parameter/command/arithmetic expansion.

๐Ÿงฉ Pathname expansion (globbing)

1
*.log

Expands to matching filenames unless nullglob or failglob is set.


๐Ÿ”ง Techniques

๐Ÿ”ง Always quote variables unless you want splitting

1
"$var"

๐Ÿ”ง Use arrays to avoid splitting issues (Bash)

1
arr=("$@")

๐Ÿ”ง Use printf instead of echo

1
printf '%s\n' "$var"

๐Ÿ”ง Use ${var%pattern} and ${var#pattern} for trimming

1
2
file="backup.tar.gz"
echo "${file%.gz}"   # backup.tar

โš ๏ธ Pitfalls

โš ๏ธ Unquoted variables causing splitting

1
rm -rf $DIR/*

If $DIR is empty โ†’ expands to rm -rf /*.

โš ๏ธ Command substitution strips newlines

1
2
lines=$(printf "a\nb\n")
printf "%s" "$lines"   # prints "ab"

โš ๏ธ Globs expanding unexpectedly

1
2
3
for f in *; do
  ...
done

If no files exist, behavior depends on shell options.

โš ๏ธ Brace expansion confusion

1
echo {1..3}.txt

Bash expands this, POSIX shells do not.


๐Ÿšจ Realโ€‘World Failures

๐Ÿšจ Failure: CI job deletes root directory

1
rm -rf "$WORKSPACE"/*

If $WORKSPACE is empty โ†’ expands to rm -rf /*.

๐Ÿšจ Failure: Command substitution breaks JSON

1
2
json=$(cat file.json)
echo "$json"   # newlines stripped โ†’ invalid JSON

๐Ÿšจ Failure: Word splitting breaks arguments

1
grep $pattern file

If $pattern contains spaces โ†’ multiple arguments.


๐Ÿ› ๏ธ Patterns

๐Ÿ› ๏ธ Pattern: Quote everything by default

1
2
"$var"
"${arr[@]}"

๐Ÿ› ๏ธ Pattern: Use arrays for lists

1
files=( *.log )

๐Ÿ› ๏ธ Pattern: Use printf for safe output

๐Ÿ› ๏ธ Pattern: Validate variables before expansion

1
: "${WORKSPACE:?must be set}"

โŒ Antiโ€‘Patterns

โŒ Antiโ€‘pattern: Using echo for structured data

echo is not reliable for JSON, XML, or binary data.

โŒ Antiโ€‘pattern: Relying on implicit splitting

1
for x in $list; do

โŒ Antiโ€‘pattern: Unquoted globs

1
rm -rf $DIR/*

๐Ÿ” Debugging

๐Ÿ” Use set -x to trace expansions

Shows expanded commands before execution.

๐Ÿ” Use printf '%q' (Bash) to inspect quoting

1
printf '%q\n' "$var"

๐Ÿ” Use declare -p to inspect variables


โš™๏ธ Performance

โš™๏ธ Avoid unnecessary command substitutions

1
2
var=$(cat file)   # slow
var=$(<file)      # fast

โš™๏ธ Avoid globbing in tight loops

Use arrays or find.


๐Ÿงต Process Control

Expansions themselves do not spawn processes, but command substitution does:

1
result=$(cmd)   # always forks

๐Ÿณ Containers

๐Ÿณ Expansion issues in entrypoints

Environment variables may be empty or unset. Always validate before expansion.


๐Ÿ›ฐ๏ธ CI/CD

๐Ÿ›ฐ๏ธ Fail fast on unset variables

1
set -u

๐Ÿ›ฐ๏ธ Validate all inputs before expansion


๐Ÿง  Summary

Shell expansions are a deterministic but complex transformation pipeline. Mastering them prevents:

  • data corruption
  • security issues
  • accidental deletions
  • broken CI pipelines

Expansions are where most shell bugs originate โ€” understanding them is essential for writing safe, predictable scripts.