$() (Command Substitution)
| Since: | All Linux | |
|---|---|---|
| macOS(2001 Cheetah) | ||
| Bash 1.0(1989) |
Command substitution ($()) embeds the output of a command as a string in another context. You can use it in variable assignments, as arguments to other commands, in echo output, and more.
Syntax
Command substitution (recommended).
$(command)
Backtick syntax (legacy, not recommended).
`command`
Assign to a variable.
variable=$(command)
Use as an argument to another command.
command1 $(command2)
Nesting ($() makes nesting easy).
$(command1 $(command2))
Usage Patterns
| Pattern | Description |
|---|---|
| var=$(cmd) | Assigns the standard output of a command to a variable. Trailing newlines are automatically removed. |
| echo "Today: $(date)" | Embeds the result of a command inside a string. |
| for f in $(ls *.txt) | Uses the command output as a list to iterate over with a for loop. |
| $(cmd1 $(cmd2)) | Nested command substitution (nesting is difficult with backticks). |
| files=$(find . -name "*.php") | Stores multi-line output in a single variable. |
Sample Code
Assign the result of a command to a variable.
sample_date_var.sh
today=$(date +%Y-%m-%d) echo "Today's date: $today"
Run the following command:
bash date_var.sh Today's date: 2026-03-06
sample_whoami_var.sh
current_user=$(whoami) echo "Current user: $current_user"
Run the following command:
bash whoami_var.sh Current user: alice
Use a command's result directly, such as counting files.
sample_count_php.sh
php_count=$(find . -name "*.php" | wc -l) echo ".php file count: $php_count"
Run the following command:
bash count_php.sh .php file count: 42
Embed command results inside a string.
echo "Hostname: $(hostname), User: $(whoami)" Hostname: myserver, User: alice
Use command output as a filename.
sample_logname.sh
log_file="app_$(date +%Y%m%d_%H%M%S).log" echo "Log file: $log_file"
Run the following command:
bash logname.sh Log file: app_20260306_143022.log
Nested command substitution. Unlike backticks, $() makes nesting straightforward.
sample_nested.sh
largest=$(basename $(ls -S | head -1)) echo "Largest file: $largest"
Run the following command:
bash nested.sh Largest file: index.php
Combine with a for loop to process a list of files.
sample_list_php.sh
echo "--- PHP file list ---"
for f in $(find . -maxdepth 1 -name "*.php" | sort); do
size=$(wc -c < "$f")
echo "$f: ${size} bytes"
done
Run the following command:
bash list_php.sh --- PHP file list --- ./ajax.php: 8340 bytes ./index.php: 5120 bytes
You can also enter a for loop directly in the terminal. After pressing Enter after do, a > prompt appears — this means the shell is waiting for more input. Enter done to execute.
for f in $(find . -maxdepth 1 -name "*.php" | sort); do
size=$(wc -c < "$f")
echo "$f: ${size} bytes"
done
./ajax.php: 8340 bytes
./index.php: 5120 bytes
Store multi-line output in a variable and process it.
sample_count_dirs.sh
dirs=$(find . -maxdepth 1 -type d) echo "Directory count: $(echo "$dirs" | wc -l)"
The following example demonstrates this:
bash count_dirs.sh Directory count: 8
Common Mistakes
Common Mistake 1: Expanding without quotes splits on word boundaries
Without double quotes, the result of command substitution is subject to word splitting and glob expansion.
sample_no_quote.sh
files=$(ls *.php)
for f in $files; do
echo "$f"
done
If filenames contain spaces, each space-separated word becomes a separate item. Always quote the result.
sample_quoted.sh
files=$(ls *.php)
for f in "$files"; do
echo "$f"
done
Common Mistake 2: Trailing newlines are removed from the output
Command substitution strips trailing newlines. If you need to preserve them, workarounds are required.
result=$(printf "line1\nline2\n") echo "$result" | wc -l 2
The two trailing newlines from printf are stripped but the internal newline between lines is kept. If you need the exact output, redirect to a file instead of using command substitution.
Notes
The result of command substitution has trailing newlines automatically removed. If you store multi-line output in a variable, the lines are preserved, but expanding without double quotes ($variable) converts newlines to spaces. To process multi-line output line by line, quote the variable ("$variable") and pass it to a while read loop.
Backtick syntax (`cmd`) is hard to nest and difficult to read, so modern scripts should use $() instead.
To pass command output as arguments to another command, xargs is also useful.
If you find any errors or copyright issues, please contact us.