This is a really nice feature in bash, avoiding the use of temporary files for commands that must receive input (or send output) via filename-arguments.
Some commands like paste(1)
work on multiple files, the names of which are passed
on the command-line:
NAME
paste -- merge corresponding or subsequent lines of files
SYNOPSIS
paste [-s] [-d list] file ...
paste(1)
basically takes 1 line from each specified file, and concatenates these
lines using separators:
$ jot 3 10 > a
$ jot 3 20 > b
$ paste -d , a b
10,20
11,21
12,22
Assuming files a
and/or b
are temporary outputs from other commands in a chain,
in order to use paste(1)
, temporary files would be used.
Bash's process-substitution syntax creates an on-the-fly fifo, reading or writing data from/to a child-process:
cat <( jot 3 10 )
10
11
12
(The fifo-name is transparently inserted into the command-line, as if a temporary file were used.)
The first example, using this trick, can be rewritten to:
paste -d , <( jot 3 10 ) <( jot 3 20 )
10,20
11,21
12,22
Similar for >( sed 's/^/> /' > read_output_file )
or similar, to create a
process reading the command's output, written to its output-file argument:
$ cp a >( sed 's/^/> /' > out )
$ cat out
> 10
> 11
> 12
(not-so-useful example, creating a sort of filter before writing the command's output to disk)