C.W.K.
Stream
Lesson 03 of 05 · published

Process Substitution

~8 min · process-substitution, compare

Level 0Window Tourist
0 XP0/95 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

Use a command's output as a file

<(cmd) turns a command's stdout into a file path the next program can read. Useful for tools like diff that take filenames, not pipes.

Compare two command outputs

diff <(ls dir1) <(ls dir2)
diff <(sort a.txt) <(sort b.txt)
comm -23 <(sort users-now.txt) <(sort users-yesterday.txt)

None of these need temp files. Bash creates a FIFO under /dev/fd/63 behind the scenes; the consumer reads from it as if it were a real file.

Outbound: >(cmd)

some_cmd >(gzip > out.gz) 2> errors.log
tar c -f >(ssh remote 'cat > backup.tar') /home

Less common but powerful: a command writes to a path; the path is actually another command's stdin.

Why not just use a pipe?

Pipes only have one input. Process substitution lets you feed two or more inputs into a tool that expects file arguments. It's the natural shape for diff / comm / paste / join.

Doesn't work in POSIX sh

Process substitution is a bash/zsh extension. POSIX sh scripts need temp files (mktemp) for the same job. Yet another reason to write modern scripts in bash, not sh.

Code

Diff two command outputs·bash
# Compare two server's installed packages
diff <(ssh boxA dpkg -l | sort) <(ssh boxB dpkg -l | sort)
# Lines in left only
comm -23 <(sort a.txt) <(sort b.txt)
# Lines in right only
comm -13 <(sort a.txt) <(sort b.txt)

External links

Exercise

Compare your global zsh aliases against another machine's: diff <(ssh office alias) <(alias). Or compare two sorted /etc/passwd files. Feel how the temp-file workflow disappears.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.