<( <LIST> ) >( <LIST> )
This only works on systems that support named pipes (FIFO - a special file) or the /dev/fd/NNNNN-syntax to access open files.
Process substitution is performed simultaneously with parameter expansion, command substitution and arithmetic expansion.
The command list <LIST> is executed and its
<( ... ) form or>( ... ) form
is connected to a FIFO or a file in /dev/fd/. The filename (where the filedescriptor is connected) is then used as a substitution for the <(...)-construct.
That, for example, allows to give data to a command that can't be reached by pipelining (that doesn't expect its data from stdin but from a file).
This code is useless, but it demonstrates how it works:
$ echo <(ls) /dev/fd/63
The output of the ls-program can be accessed by reading the file /dev/fd/63.
This is very useful in redirection statements.
A wrong piece of code to count all files in /etc is:
counter=0 find /etc | while read; do ((counter++)) done echo "$counter files"Why this is wrong? Due to the pipe, the
while read; do ... done part is executed in a subshell. That also means counter is incremented in that subshell. When the pipeline finishes, the subshell is terminated, and the counter you access is the counter from the main shell - the one at "0"!
Process substitution helps us here to avoid the pipe (which is the reason for the subshell):
counter=0 while read; do ((counter++)) done < <(find /etc) echo "$counter files"This is the normal input file redirection
< FILE, just that FILE is dynamically generated by process substitution:
< <(COMMAND)
Discussion