管道vs重定向到进程

时间:2014-08-24 13:15:59

标签: bash

寻找一些 bash-expert 解释。下一个

之间的确切区别是什么?
command1 | command2

e.g。经典管道,其中command1的stdout被重定向到command2的stdin,例如

  • bash forks两次
  • 更改文件描述符
  • 执行comman1和command2

command1 > >(command2)

结果(和bash操作)是相同的......

至少我从

得到了同样的东西
find . -print0 | xargs -0 -n1 -I% echo =%=

find . -print0 > >(xargs -0 -n1 -I% echo =%=)

> >(command)只是更长的方式说|吗?或者不是,我错过了什么?

2 个答案:

答案 0 :(得分:8)

要实现

command1 | command2
,shell会在父进程中创建一个管道,并将其一端附加到command1的输出(fd 1;它使用dup或dup2),另一端连接到command2的输入(fd 0)。

要实现

command1 > >(command 2)
,shell会创建一个FIFO。它将command2的stdin附加到FIFO(通常使用O_WRONLY标志打开),并将FIFO的名称作为command1的位置参数传递。您可以使用echo >(true)

轻松查看此内容

如果您使用

> >(foo)
这些表格确实非常相似。但是,流程替代机制更加强大。例如,你做了这样的事情:

diff -u  <(curl 'http://www.a.example.com/')  <(curl 'http://www.b.example.com/')

你不能用管道做到这一点 - 你不能有两个标准输入。

答案 1 :(得分:4)

my question中讨论了至少部分差异。

另一个区别是控制子shell中运行的进程:

$ 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