`time`の出力をファイルに書き込みます。なぜ括弧が必要なのですか?


18

timeに書き込みますstderrので2>&1、コマンドラインに追加すると出力がルーティングされるべきだと思いstdoutます。しかし、これは機能しません:

test@debian:~$ cat file 
one two three four
test@debian:~$ time wc file > wc.out 2>&1

real    0m0.022s
user    0m0.000s
sys     0m0.000s
test@debian:~$ cat wc.out 
 1  4 19 file

かっこでのみ機能します:

test@debian:~$ (time wc file) > wc.out 2>&1
test@debian:~$ cat wc.out 
 1  4 19 file

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

この場合、なぜ括弧が必要ですか?なぜ単一のコマンドtime wcとして解釈されないのですか?


3
timeシェルキーワードであるかであるかによって結果が異なることに注意してください/usr/bin/time。ここには、いくつかの記述子セット(シェル、およびtimeプロセスにアタッチされたもの)が含まれる場合があります。そして、()サブシェルによって暗示されるものを忘れないでください。(bashの専門家を待っている:p)
ジョンWHスミス

回答:


24

と、コマンド(組み込みまたはしない)、それはのような言語の予約語だではありませんか。kshbashzshtimeforwhile

パイプラインのタイミングを計るのに使用されます1

に:

time for i in 1 2; do cmd1 "$i"; done | cmd2 > redir

パイプラインを実行するようシェルに指示する特別な構文があります:

for i in 1 2; do cmd1 "$i"; done | cmd2 > redir

そして、そのためのタイミング統計を報告します。

に:

time cmd > output 2> error

それは同じで、コマンドのタイミングを計っていますがcmd > output 2> error、タイミング統計はシェルの標準エラーに残ります。

必要なもの:

{ time cmd > output 2> error; } 2> timing-output

または:

exec 3>&2 2> timing-output
time cmd > output 2> error 3>&-
exec 2>&3 3>&-

シェルのstderrがtiming-outputtimeコンストラクト(再びcommandではなく)が使用される前にリダイレクトされます(ここではtimeになりますcmd > output 2> error 3>&-)。

また、stderrがリダイレクトtimeされたサブシェルでその構成を実行することもできます。

(time cmd > output 2> error) 2> timing-output

ただし、このサブシェルはここでは必要ありませんtime。コンストラクトが呼び出されたときにリダイレクトされるのはstderrだけです。

ほとんどのシステムにはtimeコマンドもあります。timeキーワードを無効にすることで、それを呼び出すことができます。キーワードはリテラルである場合にのみ認識されるため、キーワードを引用するだけです。

'time' cmd > output 2> error-and-timing-output

しかし、形式が異なると、両方のstderrのかもしれ用心timecmdにマージされますerror-and-timing-output

また、timeコマンドは、timeコンストラクトとは対照的に、パイプライン、複合コマンド、複合関数、またはシェル組み込み関数の時間を計ることができません...

組み込みコマンドである場合、関数呼び出しまたは組み込みコマンドの時間を計ることができますが、リダイレクト、パイプライン、または複合コマンドの時間を計ることはできません。


1つのbash(どのように考えることができる)を有しているバグができるtime (cmd) 2> file(ただし、time cmd | (cmd2) 2> file例えば、)は、タイミング出力をリダイレクトfile


まあ、私はしばしばそれtimeがキーワードであり、シェルビルトインではないことを覚えておくように頭にストレスをかけます。
クオンルム

'time'実行可能ファイルを取得するための使用に関するヒントをお寄せいただきありがとうございます。書くよりも便利です/usr/bin/time(またはcommand time:-))。
アレクシス

@alexisも\time
ctrl-alt-delor

7

そこという名前のコマンドはませんtime wctimewc分離されている単語をシェルに。

現在、多くの場合という2つの別個のプログラムtimeがあります。1つはシェルキーワードで、もう1つは外部コマンドです。timeシェルキーワードであるシェルでは、を入力するtime wc ...と、シェルtimeは外部時間ユーティリティではなくそのキーワードを使用しました。

シェルがtimeキーワードを使用する場合、新しいプロセスをfork()する必要はありません。現在のtime標準入力と標準エラーは変更されません。次のリダイレクト部分:

time wc file > wc.out 2>&1

影響wcのみ。

複合コマンド(list)を使用する場合:

(time wc file) > wc.out 2>&1

シェルRAN time wc fileサブシェル内は、(time wc file)考慮された単一のコマンド、およびリダイレクト部分は今の両方を含み、その標準出力と標準エラー、影響timeなどをwc


別の形式のグループ化コマンドを使用して、新しいプロセスをフォークするコストなしで、同じ効果を作成できます{list;}

{time wc file;} > wc.out 2>&1

externalを使用する場合time、このプロセスは新しいプロセスで実行されたため、この問題に直面することはありません。

/usr/bin/time wc file > wc.out 2>&1

とを使用するのに実際的な違いはtimeあり/usr/bin/timeますか?機能的に呼び出される実行可能ファイルは同じですか?
ハシム

2

のでtime、あなたが実行しているbashの組み込み関数です。Bashはこのような特別な方法で処理します。

実際のtimeバイナリを使用する場合、期待どおりに動作します。

/usr/bin/time wc file > wc.out 2>&1

今回の出力は少し異なりますが:

 $ /usr/bin/time wc file > wc.out 
0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata1900maxresident)k
0inputs+8outputs (0major+82minor)pagefaults 0swaps

9
それが組み込みである場合、それは問題ではないでしょう。問題は、それが言語のキーワードだということです。コマンドのtime cmd > output回数cmd > output、およびtime foo | bartimes foo | bar
ステファンシャゼル

1

time時間情報を書き込むのではありません。組み込みtimeコマンドは、コマンドの完了後にシェルにこれを書き込ませます。ただし、リダイレクトはコマンドにのみ影響します。

この(time ...)場合、リダイレクトはサブシェル全体に適用されます。


0

timeはシェルに組み込まれているため、コマンドのstderrではなく、シェルのstderrに書き込みます。

括弧を使用すると、コマンド全体が、stderrをリダイレクトできる子シェルになります。

中括弧を使用すると、実際にサブシェルを開始せずに同様の結果が生成されます

  { time who ; } > /tmp/timwho >& /tmp/xx 

(はい、セミコロンが必要です)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.