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

SyntaxDirectionReturnsUse Case
$()command -> stringString outputInline substitution
<()command -> inputFile pathCommands expecting file arguments
>()output -> commandFile pathSend 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)