A command substitution (
$(...)) will be replaced by the output of the command, while a process substitution (
<(...)) will be replaced by a filename from which the output of the command may be read. The command, in both instances, will be run in a subshell.
In your case, the output from
<(pwd) may be found at
/dev/fd/63. This file ceases to exist as soon as the command that uses the command substitution has finished executing (when the
echo in your example is done).
The filename returned by a process substitution is the name of a file descriptor or named pipe, not a regular file:
Process substitution is supported on systems that
support named pipes (FIFOs) or the
/dev/fd method of naming open files.
A common use of process substitution is to pre-sort files for the
$ join <( sort file1 ) <( sort file2 )
or for removing columns from a file (here, column 2 is removed from a tab-delimited file by using
cut twice and
paste to stitch the result together):
$ paste <( cut -f 1 file ) <( cut -f 3- file )
Process substitution is more or less a syntactical shortcut for avoiding using temporary files explicitly.
Both command substitutions and process substitutions are performed in subshells:
$ echo $( t=1234; echo $t )
$ echo $t
1234 as a string argument from the command substitution.
$ cat <( t=4321; echo $t )
$ echo $t
cat get the filename of a file (named pipe/file descriptor) as its argument. The file contains the data