timeコマンドの結果をファイルへ出力するやり方を間違えたのでメモ。
ちなみにbash。
やること
a.outを実行したときの出力とそれにかかった時間をlogfileへ出力する
ダメな例
time ./a.out > logfile time ./a.out | tee logfile
上がまるっとリダイレクトしちゃうケースで、下はteeで標準出力にも表示しながら実行するケース。
散々時間かけて実行したのに、後でlogfileを見てみたらガッカリ。timeの出力だけはlogfileには書き込まれてない。
timeの結果は標準エラー出力
なのでした。
標準エラー出力も標準出力と一緒にlogfileに書き出さないとダメだね。
まだダメな例
というわけで標準エラー出力も併せてリダイレクトするよ
time ./a.out >& logfile time ./a.out > logfile 2>&1 time ./a.out 2>&1 | tee logfile
しかし、これもダメ。
./a.out >& logfile ./a.out > logfile 2>&1 ./a.out 2>&1 | tee logfile
といったtimeコマンド後ろに書いた「a.outコマンドの実行結果をエラー出力も含めてlogfileに書き出す」のtimeを計っちゃうわけ。だからtimeコマンドの結果はlogfileには書き込まれないよ。
OKな例
やりたい事は「time ./a.out」の出力をlogfileに書くんだから…
(time ./a.out) >& logfile (time ./a.out) > logfile 2&>1 (time ./a.out) 2>&1 | tee logfile
括弧で囲んじゃえー。これでうまく行く。つまりサブシェルで実行するのです。
ちなみに最近のbashは>&じゃなくて&>でも大丈夫なのね。
コマンドをグループ化する{ ;}でもOKみたい。
{ time ./a.out ; } >& logfile { time ./a.out ; } > logfile 2&1 { time ./a.out ; } 2>&1 | tee logfile
{ の後には必ずスペースを入れようね。スペースいれないと、-bash: syntax error near unexpected token `}’ って言われちゃうよ。あとセミコロン;も忘れずに。
/usr/bin/time
ところで、bash組み込みのtimeとは別にGNUのtimeコマンドというのもあるよ。/usr/bin/timeとフルパスで書いてやると実行できる。
これもbash組み込みのtime同様、標準エラー出力に結果を出力するんだけど、サブシェルで実行しなくても、
/usr/bin/time ./a.out >& logfile /usr/bin/time ./a.out > logfile 2>&1 /usr/bin/time ./a.out 2>&1 | tee logfile
と、括弧つけなくても大丈夫。もちろん括弧つけてもいい。
それに、ちゃんとファイル出力オプション-oがあるよ。
/usr/bin/time -o logfile ./a.out
でもこれだとtimeの結果しか書き込まれないので、追記オプション-aをつけて
/usr/bin/time -a -o logfile ./a.out > logfile
とやればいいっぽい(おそらく「./a.out > logfile」のtimeなんだろうけど)。
bashのtimeより詳細なデータが出るし、出力フォーマットの指定とかいろいろ柔軟に操作できるコマンドなので覚えておくとよいかもしれないね。
詳しくはman timeで。bashのtimeについてはhelp timeで。
2件のコメント
ふっくんフランク · 2013/06/27 19:13
通りすがりです。
時空を超えて感謝です。
time での結果を結構念入りにリダイレクト、
ファイルに保存しようと思ったのですが、
はまってしまい。
はぁ、bashに組み込まれているんですね。
当方、Ubuntu 12.10 amd64.
ありがとうございました。
りっちー · 2013/12/03 11:54
知らなんだ・・・