Looking for some bash-expert explanation. What is the exact difference between of the next
command1 | command2
e.g. classic pipe where the stdout of command1 is redirected to the stdin of command2, e.g.
and
command1 > >(command2)
where the result (and the bash actions) are the same...
At least i got the same from the
find . -print0 | xargs -0 -n1 -I% echo =%=
and
find . -print0 > >(xargs -0 -n1 -I% echo =%=)
Is the > >(command)
only the longer way saying |
? Or not, and I missed something?
Differences Between Pipes and Redirects To recap: A pipe passes standard output as the standard input to another command. A redirect sends a channel of output to a file.
Redirection is used to redirect the stdout/stdin/stderr, e.g. ls > log. txt . Pipes are used to give the output of a command as input to another command, e.g. ls | grep file.
Another difference is that if the file can not be written to, then the first command, with the redirection, would not even run the echo , whereas the echo would run in the second command, but tee would fail in writing to the file ( tee would still produce text on the terminal though).
So, what we learned is, the “>” is the output redirection operator used for overwriting files that already exist in the directory. While, the “>>” is an output operator as well, but, it appends the data of an existing file. Often, both of these operators are used together to modify files in Linux.
To implement
command1 | command2the shell creates a pipe in the parent process and attaches one end of it to the output (fd 1; it uses dup or dup2) of command1, and the other end to the input (fd 0) of command2.
To implement
command1 > >(command 2), the shell creates a FIFO. It attaches the command2's stdin to the FIFO (with open using the O_WRONLY flag, usually) and it passes the name of the FIFO as a positional argument to command1. You can easily see this by using
echo >(true)
.
If you use the
> >(foo)these forms are indeed very similar. However, the process subsititution mechanism is more powerful. For example you get do this kind of thing:
diff -u <(curl 'http://www.a.example.com/') <(curl 'http://www.b.example.com/')
You can't do that with pipes - you can't have two standard inputs.
At least part of a difference is discussed in my question.
An additional difference is control over which processes run in sub-shells:
$ declare -p f b
-bash: declare: f: not found
-bash: declare: b: not found
$ { f=foo; true; } | { b=bar; true; }
$ declare -p f b
-bash: declare: f: not found
-bash: declare: b: not found
$ { f=foo; true; } > >( { b=bar; true; })
$ declare -p f b
declare -- f="foo"
-bash: declare: b: not found
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With