Paul L. Snyder on 12 Jan 2009 21:08:46 -0800

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[PLUG] Process substitution

It has been quite a while since I've had a need to use process
substitution, so it wasn't at the tip of my mind during the presentation
tonight.  Here's a quick overview.  (Examples were tested in zsh, not

Process substitution is a generalized way to pipe data to commands that are
expecting files as input.  In zsh, it can take three forms: >(lst), <(lst),
and =(lst).

<(...) and >(...) exist in bash as well, and use either a file descriptor
or a named pipe.  They take the output of the command represented here by
'...' and make it available through one of those two mechanisms.  In bash,
I believe it will always be a /dev/fd/<n> file descriptor; in zsh, it will
be a named pipe as long as the system supports them, a /dev/fd file
descriptor otherwise.

To get a feel for what's going on, try running

  $ vim <(ls)

It's worth noting that for these two forms, the command is run

  $ mkdir foo1 foo2
  $ # create bar01 to bar10 in each directory
  $ touch foo{1,2}/bar{01..10}
  $ # delete files from one of the directories
  $ rm foo2/bar0[468]
  $ # compare the two directories
  $ diff <(ls foo1) <(ls foo2)

>(...) works similarly, except anything written to it will be passed to the
command inside the parentheses as input.

=(...) is not implemented in bash, and uses an actual temporary file
instead of a named pipe or /dev/fd/* file.  This is necessary if you are
using a process that wants to lseek(2) on the data, which won't work on a

I'll try to come up with some useful examples of process substitution for
next month's encore presentation at PLUG East.

Thanks to everyone who showed up tonight!

Philadelphia Linux Users Group         --
Announcements -
General Discussion  --