我本以为这段代码会打印“钱币“ 第一的:
echo foo | tee >(rev) | ( sleep 1 ; cat ; )
输出:
foo
oof
增加sleep
时间不会改变顺序。为什么那不起作用?
注意其他工具做按预期工作,例如: echo foo | pee rev 'sleep 1 ; cat'
。
答案1
在
echo foo | tee >(rev) | (sleep 1; cat)
与bash
in 类似ksh
,但不同的是zsh
, 的 stdoutrev
也是到 的管道(sleep 1; cat)
。
echo
、tee
、rev
和(...)
subshell 同时启动,但tee
写入foo\n
stdout前管道 to rev
,所以无论如何,rev
都会在writesoof
之后写入管道,所以只能放在最后。没有延迟发生。tee
foo
oof
cat
如果你想要的输出rev
不是要通过管道到达(sleep 1; cat)
,您可以使用zsh
或执行以下操作:
{ echo foo 3>&- | tee >(rev >&3 3>&-) 3>&- | (sleep 1; cat) 3>&-; } 3>&1
请注意,它的功能zsh
还有一个内置功能,因此您可以执行以下操作:tee
multios
echo foo > >(rev) > >(sleep 1; cat)
然而在:
echo foo > >(rev) | (sleep 1; cat)
的输出rev
将会通过cat
(令人困惑的是,在这种情况下它不会通过echo foo >(echo bar) | (sleep 1; cat)
)。
答案2
使用两个bash
进程替换(而不是仅一个,然后是一个管道),然后将 STDOUT 转储到 /dev/null,可以按预期工作:
echo foo | tee >(rev) >( sleep 1 ; cat ; ) > /dev/null ; sleep 1
输出:
oof
foo
笔记:
- 这第二名
sleep
防止“富" 在命令提示符后打印。 - 将延迟数减少
sleep
到某个最佳值应该会更好,但我不确定该数字应该是多少。1
有点慢,但似乎总是有效;.01
并不总是有效(即输出有时顺序错误),但.1
似乎工作得很好。