Bash Substitution
Command substitution $(), process substitution <() and >(), and the tee command for piping output.
Bash provides several substitution mechanisms for working with command output and processes.
Command Substitution - $()
Runs a command and substitutes its output as a string.
echo "Today is $(date)"
Store in Variable
count=$(wc -l < file.txt)
files=$(ls *.md)
Use Inline
echo "You have $(ls | wc -l) files"
echo "Current dir: $(pwd)"
Nesting
echo "Size: $(du -h $(which bash))"
Backticks (Legacy)
The older `command` syntax does the same thing, but $() is preferred because it nests cleanly.
# Hard to read with backticks
echo `echo \`date\``
# Clear with $()
echo $(echo $(date))
Process Substitution - <() and >()
Creates temporary file descriptors connected to commands.
Input Process Substitution - <()
Makes command output available as a file path. Useful for commands that expect file arguments.
diff <(ls dir1) <(ls dir2)
Examples
# Compare sorted versions
diff <(sort file1) <(sort file2)
# Join command output
paste <(cut -f1 data.txt) <(cut -f3 data.txt)
# Use curl output as a file
wc -l <(curl -s https://example.com)
Output Process Substitution - >()
Sends output to a command as if writing to a file.
command | tee >(process1) >(process2)
Examples
# Send to multiple processes
echo "hello" | tee >(wc -c) >(tr 'a-z' 'A-Z')
# Split log into separate files
cat data.txt | tee >(grep error > errors.log) >(grep warn > warnings.log) > /dev/null
Summary
| Syntax | Direction | Returns | Use Case |
|---|---|---|---|
$() | command -> string | String output | Inline substitution |
<() | command -> input | File path | Commands expecting file arguments |
>() | output -> command | File path | Send data to multiple commands |
The tee Command
Reads from stdin and writes to both stdout and files simultaneously. Named after a T-shaped pipe fitting.
Basic Usage
echo "hello" | tee file.txt
Prints “hello” to the terminal and writes it to file.txt.
Common Options
# Append instead of overwrite
echo "line" | tee -a file.txt
# Write to multiple files
command | tee file1.txt file2.txt
Save Output While Viewing
command | tee output.log
Sudo Redirect Workaround
Can’t redirect directly with sudo:
# This fails - redirect happens before sudo
sudo echo "text" > /etc/somefile
Use tee instead:
echo "text" | sudo tee /etc/somefile
Combining with Process Substitution
# Send to files and commands
command | tee file.txt >(grep error > errors.log)