如何确保bash管道进程不重叠?

时间:2014-07-28 18:54:52

标签: bash

如何确保在bash管道中

bash>foo | bar

bar仅在foo完成后启动?

4 个答案:

答案 0 :(得分:3)

这不是管道的工作方式。 foo | bar 始终同时运行foobar,因为它将foo的输出连接到bar的输入最小缓冲区(如果有的话)。

如果要单独运行它们,请不要使用管道;而是将输出写入文件:

foo >out
bar <out

...您还可以选择使用变量将输出存储在内存中:

out=$(foo)
bar <<<"$out"

...虽然这不是逐字节准确的(例如,丢弃尾随换行符)。

答案 1 :(得分:1)

管道用于将foo的输出连接到bar的输入。如果foo完成,bar无法获得任何输入。

也许你想要的只是

foo ; bar

如果bar需要消耗foo的输出,那么中间文件就是一个解决方案。另一个,如果grep的参数是硬编码的,则使用括号

ps aux | grep [p]attern

另一种解决方案是安装和使用[buffer][1]命令

foo | buffer -m ... | bar

-m ...缓冲区的大小足以容纳foo命令的输出。

答案 2 :(得分:1)

管道的工作方式,foobar在两个独立的子壳中运行。因此,只要foo输出可用,bar就可以使用它(通过读取它的stdin - 因为基于管道的IPC,运行的进程之间的通信两个单独的子shell完全使用FIFO队列,用于将stdoutfoo发送到bar的{​​{1}}。因此,stdin在此上下文中我不知道或关心bar是否已经结束。它只关心foo上的内容。

如果您关心stdin的完成,则必须对foobar使用其他类型的调用。

答案 3 :(得分:1)

您不能使用管道,因为它们总是同时运行。使该机制有效的正确方法是使用缓冲区:

buffer=$(foo)
echo "$buffer" | bar

或者

bar <<EOF
$(foo)
EOF
  • echo -n并没有真正严格,因为$()最后修剪0x0A