【发布时间】:2015-08-21 08:17:16
【问题描述】:
规格
不认为这会有所作为,但无论如何我都会包含它
GNU bash,版本 3.2.51
前提
假设我有一个包含多个部分的管道,如何防止部分管道在前一部分完成之前运行。
示例
在下面的示例中,我将尝试显示问题
$ echo hello | tee /dev/tty | (echo "Next";sed 's/h/m/' )
输出
Next
hello
mello
用 sleep 表示是定时关闭
$ echo hello | tee /dev/tty | (sleep 2;echo "Next";sed 's/h/m/' )
输出
hello
Next
mello
预期输出
如上
hello
Next
mello
但这显然取决于睡眠时间比上一个命令完成所需的时间长,这不是我想要的。
注意事项
我知道有更好的方法可以做到这一点,但我认为准确了解管道的工作原理对我来说是有教育意义的。
试过
尝试了等待和睡眠的变体,但没有任何效果始终如一。
这仍然会先打印 Next
$ echo hello | tee /dev/tty | sort |(echo "Next";sed 's/h/m/' )
Next
hello
mello
$ echo hello | tee /dev/tty | tac | tac |(echo "Next";sed 's/h/m/' )
Next
hello
mello
如果需要更多信息,请告诉我。
【问题讨论】:
-
使用
()在 next 和 sed 中创建另一个管道,这通常是为什么您最终会按照您的想法打印 Next ,但顺序不正确。如果你用大括号表达式{}替换它,那么tac | tac操作(如果有的话,你可以单独使用sponge)应该可以正常工作。 -
@Petesh
as you consider, out of order,不必居高临下,这显然是不正常的。此外,如果我使用大括号,那么它会挂起/等待输入。另外,您所说的无论如何都没有意义,因为即使它在another pipeline(子shell 不是管道,没有管道)中,sed 仍然会执行。 -
听起来并不居高临下;这不是我的意图。
{}的语法更严格一些 - 您必须在大括号的左右两边留有空格,并在命令的后面加上;,例如{ echo "Next"; sed 's/h/m'; }。我刚刚注意到它在我尝试过的另一个系统上不起作用。但是,如果您尝试对 echo 和 sed 进行排序,则需要一个尾随| tac | tac。 -
@Petesh 是的,我省略了尾随的
;,谢谢。但是在现在尝试之后,它仍然首先打印NEXT。也肯定只使用cat而不是tac | tac将具有与等待输入相同的效果,还是不会? -
目的是在可能异步运行的东西周围强制序列点,所以你最终得到的是:
echo hello | tee /dev/tty | cat | ( echo "Next"; sed 's/h/m/' ) | cat。