Linuxのタイミングプログラムに関するちょっとした質問:timeコマンドを使用すると、プログラムの実行時間を測定できます。
[ed@lbox200 ~]$ time sleep 1
real 0m1.004s
user 0m0.000s
sys 0m0.004s
それはうまくいきます。しかし、出力をファイルにリダイレクトしようとすると失敗します。
[ed@lbox200 ~]$ time sleep 1 > time.txt
real 0m1.004s
user 0m0.001s
sys 0m0.004s
[ed@lbox200 ~]$ cat time.txt
[ed@lbox200 ~]$
ファイルを書き込むオプション-oを使用した他の時間の実装があることは知っていますが、私の質問はそれらのオプションのないコマンドに関するものです。
助言がありますか ?
試して
{ time sleep 1 ; } 2> time.txt
「time」のSTDERRとコマンドをtime.txtに結合します
または使用する
{ time sleep 1 2> sleep.stderr ; } 2> time.txt
「sleep」からSTDERRを「sleep.stderr」ファイルに入れ、「time」からのSTDERRのみを「time.txt」に入れます
time
とタイミングをとるコマンドを角括弧で囲みます。
たとえば、次の場合、ls
を呼び出し、ls
の結果とタイミングの結果をoutfile
に書き込みます。
$ (time ls) > outfile 2>&1
または、time
からキャプチャされた出力からコマンドの出力を分離する場合:
$ (time ls) > ls_results 2> time_results
シンプル。 GNU time
ユーティリティには、そのためのオプションがあります。
ただし、シェルの組み込みtime
コマンドを使用してnotであることを確認する必要があります。少なくともbash
組み込みコマンドではそのオプションが提供されません。 time
ユーティリティの完全なパスを指定する必要があるのはそのためです。
/usr/bin/time -o time.txt sleep 1
コマンドのエラー出力が気になる場合は、組み込みのtimeコマンドを使用しながら、このようにエラーを分離できます。
{ time your_command 2> command.err ; } 2> time.log
または
{ time your_command 2>1 ; } 2> time.log
ご覧のように、コマンドのエラーはファイルに記録されます(stderr
はtime
に使用されるため)。
残念ながら、別のハンドル(3>&2
など)に送信することはできません。これは、{...}
の外部にはもう存在しないためです。
つまり、GNU時間を使用できる場合は、@ Tim Ludwinskiが言ったことを実行してください。
\time -o time.log command
'time'コマンドの出力はエラー出力であるため、標準出力をリダイレクトしてさらに処理する方が直感的です。
{ time sleep 1; } 2>&1 | cat > time.txt
Bash組み込みの代わりにGNU timeを使用している場合は、試してください
time -o outfile command
(注:GNU時刻の形式は、組み込みのbashとは少し異なります)。
&>out time command >/dev/null
あなたの場合
&>out time sleep 1 >/dev/null
それから
cat out
私は最終的に使用しました:
/usr/bin/time -ao output_file.txt -f "Operation took: %E" echo lol
#!/bin/bash
set -e
_onexit() {
[[ $TMPD ]] && rm -rf "$TMPD"
}
TMPD="$(mktemp -d)"
trap _onexit EXIT
_time_2() {
"$@" 2>&3
}
_time_1() {
time _time_2 "$@"
}
_time() {
declare time_label="$1"
shift
exec 3>&2
_time_1 "$@" 2>"$TMPD/timing.$time_label"
echo "time[$time_label]"
cat "$TMPD/timing.$time_label"
}
_time a _do_something
_time b _do_another_thing
_time c _finish_up
これには、サブシェルが生成されないという利点があり、最終的なパイプラインでは、stderrが実際のstderrに復元されます。
csh
を使用している場合は、次を使用できます。
/usr/bin/time --output=outfile -p $Shell -c 'your command'
例えば:
/usr/bin/time --output=outtime.txt -p csh -c 'cat file'
元のプロセスのstdoutとstderrに触れたくない場合は、stderrをファイル記述子3にリダイレクトして戻すことができます。
$ { time { Perl -le "print 'foo'; warn 'bar';" 2>&3; }; } 3>&2 2> time.out
foo
bar at -e line 1.
$ cat time.out
real 0m0.009s
user 0m0.004s
sys 0m0.000s
ラッパー(cronジョブなど)にそれを使用して、ランタイムを監視できます。
#!/bin/bash
echo "[$(date)]" "$@" >> /my/runtime.log
{ time { "$@" 2>&3; }; } 3>&2 2>> /my/runtime.log