`tee` 和 `bash` 进程替换顺序

`tee` 和 `bash` 进程替换顺序

我本以为这段代码会打印“钱币“ 第一的:

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)

bashin 类似ksh,但不同的是zsh, 的 stdoutrev也是到 的管道(sleep 1; cat)

echoteerev(...)subshel​​l 同时启动,但tee写入foo\nstdout管道 to rev,所以无论如何,rev都会在writesoof之后写入管道,所以只能放在最后。没有延迟发生。teefoooofcat

如果你想要的输出rev 不是要通过管道到达(sleep 1; cat),您可以使用zsh或执行以下操作:

{ echo foo 3>&- | tee >(rev >&3 3>&-) 3>&- | (sleep 1; cat) 3>&-; } 3>&1

请注意,它的功能zsh还有一个内置功能,因此您可以执行以下操作:teemultios

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似乎工作得很好。

相关内容