In addition to widely used shell features like file globing and command substitution, modern shells like bash or zsh support something that is called process substitution. The goal of process substitution is to enable syntax which will allow us to get some commands marked within special characters behave as they were regular files. Common special characters for both mentioned shells are:
Off course, this was a simple usage pattern and nobody would use process substitution in this way instead of classic pipe scenario. But suppose a situation where you want a command to operate on results of more than one command. For example, you want to compare content of two directories (let's forget on dircmp command for a moment):
<(command list)In addition to these, zsh adds additional syntax in form of:
>(command list)
=(command list)Lets start with
<() syntax. In it's simplest form, it can behave just as a regular pipe. For example, this is completely equivalent syntax:ls -l | sortor
sort <(ls -l)What actually happens under the hood is that output of
ls -l is connected to sort command through the mechanism of named pipes (FIFOs) or by using a file in /dev/fdOff course, this was a simple usage pattern and nobody would use process substitution in this way instead of classic pipe scenario. But suppose a situation where you want a command to operate on results of more than one command. For example, you want to compare content of two directories (let's forget on dircmp command for a moment):
diff <(ls dir1) <(ls dir2)Here the command acts just like you have saved output of both
ls commands to separate files, and then ran diff on those two files. Or for example, you could use something like:paste <(cut -f1 file1) <(cut -f2 file2)Or maybe you want to edit the output of some complex command directly into your favorite text editor - no problem, just use syntax similar to this:
vi <(ls -l /etc)Now when you know how to use
<(), usage pattern for >() is straightforward. You can send the standard output of a command to more than one command. For example (just make sure that MULTIOS option is set in your shell before running this, ie setopt multios for zsh):ls > >(sort) > >(sort -r)If you are using zsh (and you should! :), you can also use
=() snytax. The only difference between this syntax and <() or >() is that =() actually creates a file on filesystem instead of using FIFO. This comes handy if command you are substituting process to is using system calls like lseek(2).