我以為這段程式碼會印出“錢幣「 第一的:
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
似乎工作得很好。