Skip to content
Process Substitution and Pipelines
step 1/4

Reading — step 1 of 4

Learn

~1 min readRobust Scripting

Process substitution <(...) makes a command's output look like a file. Powerful for diffing, joining, and any command that wants a filename.

diff <(sort file1) <(sort file2)        # diff sorted versions, no temp files

comm -12 <(sort a.txt) <(sort b.txt)     # lines common to both

while read line; do
    process "$line"
done < <(curl -s api.example.com)         # feed curl output as stdin

<(cmd) returns a path like /dev/fd/63 — a file descriptor backed by a pipe.

Output process substitution >(...):

run_test 2> >(grep -v 'INFO' > errors.log)

Stderr is piped through grep then redirected to errors.log — without a temp file.

tee for splitting one stream into multiple:

build_thing | tee build.log | grep ERROR

Both build.log gets the full output AND the pipeline filters for ERROR.

Named pipes (FIFO) for cross-process IPC:

mkfifo /tmp/pipe

# Process A:
echo "hello" > /tmp/pipe

# Process B:
read -r msg < /tmp/pipe
echo "got: $msg"

FIFOs are real filesystem objects (created by mkfifo), but they behave like pipes — block until both ends are connected.

Coproc — bidirectional pipe to a child:

coproc CALC { bc -l; }
echo "3 + 4" >&"${CALC[1]}"      # write to coproc's stdin
read result <&"${CALC[0]}"        # read coproc's stdout
echo "$result"                     # 7

Performance — fork costs:

  • Each subshell (...) forks: cheap but not free (~ms)
  • Each pipe stage forks
  • Parameter expansion ${var//x/y} is in-process — much faster than echo $var | sed s/x/y/g

Tip: avoid cat file | grep, use grep file. Avoid cat file | wc -l, use wc -l < file.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…

Process Substitution and Pipelines — Bash Advanced