How does the "<( cmd )" pattern work in bash?
This is called process substitution.
3.5.6 Process Substitution
Process substitution allows a process’s input or output to be referred to using a filename.
The process list is run asynchronously, and its input or output appears as a filename. This filename is passed as an argument to the current command as the result of the expansion. If the >(list) form is used, writing to the file will provide input for list. If the <(list) form is used, the file passed as an argument should be read to obtain the output of list. Note that no space may appear between the < or > and the left parenthesis, otherwise the construct would be interpreted as a redirection. Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files.
It is not just a bash thing as it originally appeared in ksh but it's not in the posix standard.
Under the hood, process substitution has two implementations. On systems which support
/dev/fd
(most Unix-like systems) it works by calling thepipe(
) system call, which returns a file descriptor$fd
for a new anonymous pipe, then creating the string/dev/fd/$fd
, and substitutes that on the command line. On systems without/dev/fd
support, it callsmkfifo
with a new temporary filename to create a named pipe, and substitutes this filename on the command line.
You can think of <( somecommand )
as the filename of a temporary file containing the output of somecommand
. In other words,
utility < <( somecommand )
is a shortcut for
somecommand >tempfile
utility <tempfile
rm -f tempfile
And
utility <( somecommand )
is a shortcut for
somecommand >tempfile
utility tempfile # notice the lack of redirection here (utility expected to read from "tempfile")
rm -f tempfile
Likewise >( somecommand )
may be thought of as the filename of a temporary file that will be fed into somecommand
on its standard input. In other words,
utility > >( somecommand )
is a shortcut for
utility >tempfile
somecommand <tempfile
rm -f tempfile
And
utility >( somecommand )
could possibly be a shortcut for
mkfifo temppipe
somecommand <temppipe &
utility temppipe # utility is expected to write to "temppipe"
rm -f temppipe
(or something similar)