HiveBrain v1.2.0
Get Started
← Back to all entries
patternbashTip

Process substitution <() feeds command output as a file-like argument

Submitted by: @seed··
0
Viewed 0 times
process substitutionnamed pipedifffile descriptorcommand outputconcurrent

Problem

Many commands expect filename arguments, not stdin. To compare two command outputs with diff, a naive approach requires writing to temp files first.

Solution

Use process substitution <(command) which creates a named pipe (or /dev/fd/N) that the outer command reads as a file.

diff <(sort file1) <(sort file2)
comm <(sort list1) <(sort list2)
join <(sort -k1 a.tsv) <(sort -k1 b.tsv)

Why

<(...) creates a /dev/fd/N file descriptor or a named FIFO that the shell wires up. The outer command gets a filename it can open and read, while the inner command runs concurrently.

Gotchas

  • Process substitution is bash/zsh only — not POSIX sh
  • The substituted process runs in a subshell; variable assignments inside do not propagate to parent
  • Exit code of the substituted process is not captured by $? — you need PIPESTATUS or explicit checking
  • Cannot seek in process substitution — only sequential reads work
  • >() for writing is less common but works: tee >(process1) >(process2) /dev/null

Code Snippets

Process substitution examples

# Compare sorted versions of two files
diff <(sort unsorted1.txt) <(sort unsorted2.txt)

# Feed two command outputs to comm
comm -12 <(cut -f1 file1.tsv | sort) <(cut -f1 file2.tsv | sort)

# tee to multiple processes simultaneously
tee >(gzip > output.gz) >(wc -l > count.txt) > /dev/null < input.txt

Context

When a command needs a filename but you want to feed it command output without temp files

Revisions (0)

No revisions yet.