Terminal · intermediate
Command substitution
Command substitution runs a nested command and replaces the substitution with its standard output after removing trailing newline characters.
Why it matters
It lets output become an argument or assignment value, but quoting and trailing-newline removal make it unsuitable for preserving arbitrary byte records.
Mental model
How to reason about command substitution
Start a subshell environment, capture descriptor 1 completely, remove trailing newlines, insert the result into the outer command, then apply context-dependent shell expansion rules.
Analogy
It is a clerk who completes a subtask, trims blank line endings from the written result, and inserts that result into the unfinished outer form.
Examples
See the boundary, not just the happy path
Worked example · Capture a single value
revision=$(git rev-parse --short HEAD)The command's stdout becomes the assignment value, and assignment context avoids ordinary word splitting and filename expansion.
Worked example · Preserve one argument
printf 'release: %s\n' "$(date +%F)"Double quotes keep the substituted text within one argument after the nested command's trailing newline is removed.
Avoid · Iterating over filenames
for path in $(find . -type f); do process "$path"; doneUnquoted substitution is split and globbed, so whitespace and wildcard characters inside pathnames destroy record boundaries.
Common mistakes
Misconceptions to remove early
Expecting trailing newlines to survive
The shell removes all trailing newline characters from command-substitution output; use a file or stream protocol when exact preservation matters.
Using legacy backticks for nested expressions
$(...) is easier to nest and has clearer escaping rules; backticks make complex commands needlessly fragile.
Quick check
Can you predict the result?
1. What happens to trailing newline characters in $(command) output?
- • The shell removes them.
- • They become spaces in every context.
- • They are preserved exactly.
2. Why should a command substitution used as one argument usually be double-quoted?
Keep building