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

相關內容