Skip to content
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 a temporary file. On systems that support it, bash commonly exposes an open file descriptor through a path such as /dev/fd/63; otherwise the shell may create a named FIFO. The consumer opens that path as an input stream, so a tool that must seek like a regular file or reopen the same input may fail. Process substitution fits consumers that read once in order.

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.

The inner command can fail out of sight

The outer consumer's exit status may not report a failure inside process substitution. For critical automation, capture and validate each producer separately.

A temporary file can be the clearer design

Use one when input must be reopened, evidence must survive failure, or production and consumption need separate checkpoints.

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.