Process Substitution
Treat command output as files — compare, join, and loop without temp files.
Comparing Output (diff/comm/join)
diff <(cmd1) <(cmd2)
Creates named pipes under /dev/fd/. No temp files touch disk.
diff <(ssh host1 cat /etc/hosts) <(ssh host2 cat /etc/hosts)
diff <(sort file1) <(sort file2)
Sort both inputs before comparing so line order does not produce false differences.
diff <(dig @10.50.1.50 example.com +short) <(dig @8.8.8.8 example.com +short)
vimdiff <(curl -s https://api/v1/config) <(cat local-config.json)
comm <(sort list1.txt) <(sort list2.txt)
comm -23 <(sort expected.txt) <(sort actual.txt)
-23 suppresses columns 2 and 3, leaving only items unique to the first file.
comm -12 <(sort group1.txt) <(sort group2.txt)
-12 suppresses unique-to-each columns, showing only shared items.
join <(sort file1) <(sort file2)
Both files must be sorted on the join field.
Joining & Pasting
paste <(cut -d: -f1 /etc/passwd) <(cut -d: -f7 /etc/passwd)
paste <(seq 5) <(seq 5 | awk '{print $1*$1}')
paste merges parallel streams as tab-separated columns.
Loop Input
while IFS= read -r line; do echo "processing: $line"; done < <(find . -name "*.py")
< <(cmd) feeds process substitution as stdin to the while loop. Runs in the current shell, so variable assignments persist.
while IFS= read -r host; do ssh "$host" uptime; done < <(awk '/^[^#]/' hosts.txt)
Output Splitting (tee)
tee >(gzip > backup.gz) >(sha256sum > backup.sha256) > /dev/null < data.bin
One read pass produces both outputs.
cmd | tee >(grep ERROR > errors.log) >(grep WARN > warnings.log) > full.log
Single command’s output routed to multiple filtered log files.
cat <(head -1 data.csv) <(tail -n +2 data.csv | sort -t, -k2)
Loading & Sourcing
source <(kubectl completion bash)
source <(vault read -field=data secret/env | base64 -d)
mapfile -t results < <(find . -name "*.conf" -type f)
Handles spaces in filenames correctly. -t strips trailing newlines.
wc -l < <(grep -r "TODO" --include="*.py" .)
Cleaner than a pipe because $? reflects `wc’s exit status, not `grep’s.