time
1つのパイプ出力から別のパイプ出力を持つ2つの個別のコマンドで構成されるコマンドが必要です。たとえば、次の2つのスクリプトを考えます。
$ cat foo.sh
#!/bin/sh
sleep 4
$ cat bar.sh
#!/bin/sh
sleep 2
さて、どのようにtime
かかった時間を報告することができますかfoo.sh | bar.sh
(そして、はい、ここではパイプが意味をなさないことを知っていますが、これは単なる例です)?パイプなしでサブシェルで順番に実行すると、期待どおりに動作します:
$ time ( foo.sh; bar.sh )
real 0m6.020s
user 0m0.010s
sys 0m0.003s
しかし、パイピングすると動作しません:
$ time ( foo.sh | bar.sh )
real 0m4.009s
user 0m0.007s
sys 0m0.003s
$ time ( { foo.sh | bar.sh; } )
real 0m4.008s
user 0m0.007s
sys 0m0.000s
$ time sh -c "foo.sh | bar.sh "
real 0m4.006s
user 0m0.000s
sys 0m0.000s
私は同様の質問(複数のコマンドで時間を実行し、時間出力をファイルに書き込む方法)を読み、スタンドアロンのtime
実行可能ファイルも試しました:
$ /usr/bin/time -p sh -c "foo.sh | bar.sh"
real 4.01
user 0.00
sys 0.00
パイプのみを実行する3番目のスクリプトを作成しても機能しません。
$ cat baz.sh
#!/bin/sh
foo.sh | bar.sh
そして、その時間:
$ time baz.sh
real 0m4.009s
user 0m0.003s
sys 0m0.000s
興味深いことに、time
最初のコマンドが終了するとすぐに終了するようには見えません。に変更bar.sh
した場合:
#!/bin/sh
sleep 2
seq 1 5
そしてtime
再び、私はtime
前に出力が印刷されることを期待していましたseq
が、そうではありません:
$ time ( { foo.sh | bar.sh; } )
1
2
3
4
5
real 0m4.005s
user 0m0.003s
sys 0m0.000s
レポート1を印刷する前に終了するのを待っているにもかかわらずtime
、実行にかかった時間はカウントされないようです。bar.sh
すべてのテストはArchシステムで実行され、bash 4.4.12(1)-releaseを使用しました。私はこれが一部であるプロジェクトにのみbashを使用することができますのでzsh
、他の強力なシェルがそれを回避できる場合でも、それは私にとって実行可能なソリューションではありません。
それで、パイプされた一連のコマンドの実行にかかった時間を取得するにはどうすればよいですか?そして、私たちがそれに取り組んでいる間に、なぜ機能しないのですか?time
最初のコマンドが終了するとすぐに終了するようです。どうして?
私はこのようなもので個々の時間を取得できることを知っています:
( time foo.sh ) 2>foo.time | ( time bar.sh ) 2> bar.time
しかし、すべてを単一の操作として時間計測することが可能かどうかを知りたいです。
1 これはバッファの問題ではないようです。スクリプトをで実行しようunbuffered
とstdbuf -i0 -o0 -e0
しましたが、time
出力前に数値が出力されたままでした。