Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pipe vs redirect into process

Tags:

bash

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.

  • bash forks itself two times
  • changes the file descriptors
  • exec the comman1 and command2

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?

like image 395
kobame Avatar asked Aug 24 '14 13:08

kobame


People also ask

What is the difference between piping and redirecting?

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.

What is redirection and pipes?

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.

What is the key difference between a redirect and a tee?

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).

What is the difference between the output redirections and >>?

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.


2 Answers

To implement

command1 | command2
the 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.

like image 192
James Youngman Avatar answered Oct 02 '22 15:10

James Youngman


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
like image 39
Etan Reisner Avatar answered Oct 02 '22 14:10

Etan Reisner