Explain process substitution in Bash. How does it differ from pipes, and when is it essential?
Quick Answer
Process substitution <(cmd) creates a temporary file descriptor for a command's output, allowing commands that require file arguments to read from another command's output. Unlike pipes, it doesn't create a subshell for the reading command.
Detailed Answer
Process Substitution
<(command) creates a /dev/fd/N file descriptor that contains the output of command. The receiving command reads from it as if it were a regular file.
Why it matters vs pipes
With a pipe: cmd1 | while read line; do ((count++)); done; echo $count → The while loop runs in a subshell, so $count is lost after the pipe ends.
With process substitution: while read line; do ((count++)); done < <(cmd1); echo $count → The while loop runs in the current shell, so $count is preserved.
Use Cases
1. Diff two commands: diff <(sort file1) <(sort file2) — compare sorted outputs without temp files 2. Feed multiple inputs: paste <(cut -f1 file1) <(cut -f2 file2) — combine fields from different files 3. Preserve variables in loops: Read from process substitution instead of piping into a while loop 4. Named pipe without mkfifo: Process substitution handles creation and cleanup automatically
Output process substitution `>(command)` writes to a command as if it were a file
tee >(gzip > backup.gz) >(wc -l > count.txt) > /dev/null
Code Example
# Problem: pipe creates subshell, variable lost
count=0
echo -e "a\nb\nc" | while read -r line; do
((count++))
done
echo "Count: $count" # Prints 0! (subshell)
# Solution: process substitution
count=0
while read -r line; do
((count++))
done < <(echo -e "a\nb\nc")
echo "Count: $count" # Prints 3! (current shell)
# Diff two remote files without downloading
diff <(ssh server1 cat /etc/nginx/nginx.conf) \
<(ssh server2 cat /etc/nginx/nginx.conf)
# Compare Kubernetes resources across clusters
diff <(kubectl --context=prod get deploy -o yaml) \
<(kubectl --context=staging get deploy -o yaml)
# Tee to multiple destinations
tar czf - /var/log | tee >(md5sum > checksum.txt) > backup.tar.gzInterview Tip
The subshell variable loss problem is the classic gotcha that catches even experienced engineers. Process substitution is the clean solution. The diff two remote files example is memorable and practical.