「grep」は「time」では機能しないのですか?

「grep」は「time」では機能しないのですか?

なぜtime ls | grep realこれを出力するのか

real    0m0.002s
user    0m0.000s
sys     0m0.002s

単に

real    0m0.002s

入力すると

echo -e 'real\t0m0.002s\nuser\t0m0.000s\nsys\t0m0.002s\n' | grep real

私は期待通りの結果を得ました。

real    0m0.002s

これは効果があることがわかった

(time ls)  2>&1 > /dev/null | grep real

このコマンドは何をしますか?

答え1

なぜtime ls | grep real期待通りに動作しないのでしょうか。

timeは予約語でありbash、 とは異なる動作をします/usr/bin/time

パイプラインの前に時間予約語がある場合、その実行によって消費された経過時間、ユーザー時間、システム時間が報告されます。パイプラインが終了すると

ソースbash(1): GNU Bourne-Again SHell - Linux マニュアルページ

また、time標準出力ではなく標準エラーに出力します。

次のコマンドを使用します。

(time ls) 2>&1 >/dev/null | grep real 

ノート:

  • (andはand)コマンドをグループ化します(したがって、これらのコマンドが最初に評価されます)。timels

  • 2>&1 >/dev/nullまず stderr を stdout (パイプ) にリダイレクトし、次に stdout を にリダイレクトします/dev/null

    したがって、stderr はパイプに送られ、stdout はどこにも送られません。


参考文献

答え2

はい、動作しますが、I/O リダイレクトが少し必要になります :)

$ exec 3>&1 4>&2
{ time sleep 1 1>&3 2>&4; } 2>&1 |
    grep 'real'    
exec 3>&- 4>&-

出力:

real    0m1,003s

読むバッシュ FAQ#32そしてI/O リダイレクトのチュートリアル


もっと簡単な方法:

$ TIMEFORMAT=%R
$ time sleep 1
1,003

答え3

ここでは2つの問題があります。

まず、そして最も重要なことは、「time」は出力を stdout ではなく stderr (標準エラー) に送信するため、特別な対策を講じない限り、通常のリダイレクト コマンドによってキャプチャされないことです。

2 番目に、time は通常のプログラムではなく、シェルによって直接解釈される特別な組み込みコマンドです (bash、csh、tcsh などのシェルの場合)。したがって、time は非標準的な方法で動作し、残りのコマンドライン全体の時間を計測します (非常に特殊なシェルを使用している場合を除く)。

したがって、(bash を使用して) 必要な結果を得るには、以下を使用する必要があります。

(time ls) 2>&1 | grep real

これはサブシェルで「ls」を実行し、時間を計ります[(時間 ls)] 、標準エラーを標準出力に送信する[ 2>&1 ]、そして標準出力を「grep」に送信します[| grep]。

最後に使用した部分「>?dev/null」は、単語「real」が含まれていた場合に備えて、ls コマンド自体からの通常の出力を破棄します。

答え4

timeは ではなくコンソールに直接書き込むようですstdout。つまり、 を追加してもコマンドまたはパイプラインからの出力は影響を受けませんtime

したがって、パイプライン全体の時間が計測されるため、grepいずれにしても完了後に生成される時間レポートは表示されません。grep

関連情報