なぜ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)
コマンドをグループ化します(したがって、これらのコマンドが最初に評価されます)。time
ls
2>&1 >/dev/null
まず stderr を stdout (パイプ) にリダイレクトし、次に stdout を にリダイレクトします/dev/null
。したがって、stderr はパイプに送られ、stdout はどこにも送られません。
参考文献
- Linux の Bash コマンドラインの AZ インデックス- Bash コマンドラインに関連するあらゆることに関する優れたリファレンス。
- 括弧- 括弧を使用して式をグループ化および展開します。
- 構文リダイレクト- リダイレクトとプロセスの置換。
- Bash リファレンスマニュアル: リダイレクト
- 図解リダイレクトチュートリアル [Bash Hackers Wiki]
答え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