Have you seen <( sub shell code )
in a shell script and wonder how it works?
It is called process substitution.
The shell substitutes it by a special file (device or fifo).
The ( sub shell code ) is run asynchronously in the background. Its output becomes the data of the special file.
You can see the special file names with e.g.
echo <( ls ) <( ls / )
and list their data with
cat <( ls ) <( ls / )
As usual you can redirect a file with <
tr '[:lower:]' '[:upper:]' < <( ls )
Note: there must be be a space between the <
token and the <(
token.
Note: the standard only allows one <
redirection.
The ls
runs asynchronously in the background (sub shell) while the tr
runs in the foreground (main shell).
This is pretty much comparable with the pipe mechanism:
ls | tr '[:lower:]' '[:upper:]'
but in a standard shell the ls
runs in the foreground and the tr
runs asynchronously in the background.
Note: ksh and zsh run the last part of a pipe in the foreground!
That was all about process substitution as input.
There is a further usage for output:
ls > >( tr '[:lower:]' '[:upper:]' )
Yet it is rarely seen. It is pretty much the same as the "bread and butter" pipe
ls | tr '[:lower:]' '[:upper:]'
Arguments to commands are usually input files, not output files. And the output goes to stdout, so if you happen to see >( )
then certainly with a preceding >
redirection.
Few commands like sort
can directly create an output file.
sort -o >( tr '[:lower:]' '[:upper:]' ) /etc/group
Lesson learned:
process substitution for input is often useful.
process substitution for output is for geeks.