`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)

ではbashと同様ですkshが、 とは異なりzsh、 の stdoutrevも へのパイプです(sleep 1; cat)

echo、、teeおよびrevサブシェル(...)は同時に起動されますが、stdoutにtee書き込まれますfoo\n前にパイプは に書き込まれるためrev、いずれにしても は の書き込み後にパイプにrev書き込まれるため、最後にしか来ません。遅延は発生しません。oofteefoooofcat

出力を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プロセス置換を 2 つ (1 つではなく、パイプ)使用し、STDOUT を /dev/null にダンプすると、期待どおりに動作します。

echo foo | tee >(rev) >( sleep 1 ; cat ; ) > /dev/null ; sleep 1

出力:

oof
foo

ノート:

  • 2番目 sleep防止する」フーコマンドプロンプトの後に「」が印刷されないようにする。
  • 遅延数を最適な値まで減らすとsleep良いのですが、その数値が何であるべきかはわかりません。 1少し遅いですが、常に機能しているようです。.01常に機能するとは限りませんが (つまり、出力が間違った順序になることがあります)、.1うまく機能しているようです。

関連情報