シェルでプログラムの実行時間を取得する


407

いくつかの異なる条件下でLinuxシェルで何かを実行し、各実行の実行時間を出力できるようにしたいと考えています。

これを行うPerlスクリプトまたはPythonスクリプトを作成できることはわかっていますが、シェルでそれを行う方法はありますか?(たまたまbashです)



TicksWindowsケースのようなものを取得することは可能ですか?
freeforall tousez 2014年

回答:


534

組み込みtimeキーワードを使用します。

$のヘルプ時間

時間:時間[-p]パイプライン
    PIPELINEを実行し、リアルタイム、ユーザーのCPU時間、
    終了時にPIPELINEの実行に費やされたシステムCPU時間。
    戻り状況は、PIPELINEの戻り状況です。`-p 'オプション
    わずかに異なる形式でタイミング要約を出力します。これは
    出力フォーマットとしてのTIMEFORMAT変数の値。

例:

$ time sleep 2
実質0m2.009s
ユーザー0m0.000s
sys 0m0.004s

1
これは次のようなコマンドでどのように使用されtime -p i=x; while read line; do x=x; done < /path/to/file.txtますか?whileループの前に何も置かない限り、即座に0.00を返します。
natli

これは貧弱な「時間」バージョンで、bash組み込みです。外部の「時間」コマンドはどこにありますか?
Znik

6
@ Znik、/ usr / bin / timeを試してください
Mark Rajcok

10
@natli:ながらtime缶時間(バッシュであることの美徳であるとして、パイプライン全体のキーワード、あなたが使用する必要がある)groupコマンドを{ ...; ...; }時間に)複数のコマンド:time -p { i=x; while read line; do x=x; done < /path/to/file.txt; }
mklement0

2
システムにインストールした時間のすべてのバージョンを表示するには、次を使用できますtype -a time
spinup

120

time(1)timeを使用すると、組み込みのbash (Robert Gambleが言及)よりもはるかに詳細な情報を取得できます。通常これはです。/usr/bin/time

編集者注:シェルのキーワードではなく外部ユーティリティ を確実に呼び出すには、次のように呼び出します。はPOSIX必須のユーティリティですが、サポートするために必要なオプションはだけです。 特定のプラットフォームは、特定の非標準の拡張機能を実装します。以下に示すように、GNUのユーティリティで動作します(質問はタグ付けされていますtimetime /usr/bin/time
time-p
-vtime); BSD / macOS実装は-l、同様の出力を生成するために使用します-を参照してくださいman 1 time

詳細な出力の例:


$ /usr/bin/time -v sleep 1
       Command being timed: "sleep 1"
       User time (seconds): 0.00
       System time (seconds): 0.00
       Percent of CPU this job got: 1%
       Elapsed (wall clock) time (h:mm:ss or m:ss): 0:01.05
       Average shared text size (kbytes): 0
       Average unshared data size (kbytes): 0
       Average stack size (kbytes): 0
       Average total size (kbytes): 0
       Maximum resident set size (kbytes): 0
       Average resident set size (kbytes): 0
       Major (requiring I/O) page faults: 0
       Minor (reclaiming a frame) page faults: 210
       Voluntary context switches: 2
       Involuntary context switches: 1
       Swaps: 0
       File system inputs: 0
       File system outputs: 0
       Socket messages sent: 0
       Socket messages received: 0
       Signals delivered: 0
       Page size (bytes): 4096
       Exit status: 0


2
あなたはたまたまどんなdebianパッケージが出てくるのか知りませんか?デフォルトでインストールされていないようだ
ʞɔıu

1
私はあなたの投稿ロバートを参照していた。あなたが提案するコマンドがbashの組み込みではないという意味でない限り?
grepsedawk 2008

24
驚くほど、それは「時間」と呼ばれるパッケージからインストールされます。
ポールトンブリン

2
/ usr / bin / timeからの出力は、「0.00user 0.00system 0:02.00elapsed 0%CPU(0avgtext + 0avgdata 0maxresident)k 0inputs + 0outputs(0major + 172minor)pagefaults 0swaps」
Paul Tomblin

4
@Nick:「sudo apt-get install time」。
Robert Gamble

79
#!/bin/bash
START=$(date +%s)
# do something
# start your script work here
ls -R /etc > /tmp/x
rm -f /tmp/x
# your logic ends here
END=$(date +%s)
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"

14
もっと簡単な方法があります。Bashは自動的に特別な変数$ SECONDSを計算し、外部の日付コマンドに基づく再計算は不要です。$ SECONDS変数は、起動時にbashスクリプトが実行されている秒数を保持します。この変数には、いくつかの特別なプロパティがあります。マニュアルページを参照してください:D
Znik

私はコメントで上記と方法の両方を試しました。1回目に「不正な変数」エラーが発生し、2回目に「不明な変数」が表示される
DrBwts

45

ごとのデルタ測定については、gnomonを試してください。

moreutilsのtsのようなコマンドラインユーティリティ。タイムスタンプ情報を別のコマンドの標準出力に付加します。長時間かかっているプロセスの履歴記録が必要な、長期実行プロセスに役立ちます。

--highまたは--mediumオプションを使用して、長さのしきい値を秒単位で指定することもできます。このしきい値を超えると、gnomonはタイムスタンプを赤または黄色で強調表示します。また、他にもいくつかのことができます。

例


3
すばらしいヒントですが、明確にする必要があります。これは、ごとのタイミングに役立ちますが、そのようなきめの細かいタイミングをとるとオーバーヘッドが全体のタイミングに大幅に追加されます。
mklement0 2016年

2
素晴らしいユーティリティ..共有してくれてありがとう
Kishan B

19

より正確にしたい場合は、%Nwithを使用しますdate(整数のみを処理するbcため、diffに使用し$(())ます)。

方法は次のとおりです。

start=$(date +%s.%N)
# do some stuff here
dur=$(echo "$(date +%s.%N) - $start" | bc)

printf "Execution time: %.6f seconds" $dur

例:

start=$(date +%s.%N); \
  sleep 0.1s; \
  dur=$(echo "$(date +%s.%N) - $start" | bc); \
  printf "Execution time: %.6f seconds\n" $dur

結果:

Execution time: 0.104623 seconds

15

後で時間を使用して計算する場合は、-fオプションを使用して時間を節約するコード/usr/bin/timeを出力する方法を学びます。以下は、クラス全体の学生のプログラムの実行時間を取得してソートするために最近使用したコードです。

fmt="run { date = '$(date)', user = '$who', test = '$test', host = '$(hostname)', times = { user = %U, system = %S, elapsed = %e } }"
/usr/bin/time -f "$fmt" -o $timefile command args...

私は後ですべての$timefileファイルを連結し、出力をLuaインタープリターにパイプしました。Pythonやbashなど、好きな構文であれば何でも同じことができます。私はこのテクニックが大好きです。


注:フルパス/usr/bin/timeが必要なのはwhich time、別の方法で通知されますが、単にを実行するとtimetime引数を受け入れないシェルのバージョンが実行されるためです。
ケビンダイス

私は行くだろうenv time:-)
チロSantilli郝海东冠状病六四事件法轮功

13

秒の精度だけが必要な場合は、組み込み$SECONDS変数を使用できます。これは、シェルが実行されている秒数をカウントします。

while true; do
    start=$SECONDS
    some_long_running_command
    duration=$(( SECONDS - start ))
    echo "This run took $duration seconds"
    if some_condition; then break; fi
done

10

あなたは使用することができますtimeし、サブシェル ()

time (
  for (( i=1; i<10000; i++ )); do
    echo 1 >/dev/null
  done
)

または同じシェルで{}

time {
  for (( i=1; i<10000; i++ )); do
    echo 1 >/dev/null
  done
}

2つの同一のコードスニペットを投稿しました。あなたはそこで何か違うものを持っているつもりだったに違いありません。
スターソン、

3
@StasBekmanは真ではありません。最初に()(新しいコンテキスト、サブシェル)を使用し、その他を{}(同じシェル、同じコンテキスト)で使用します
Eduardo Cuomo

ああ!私は2つを真剣に見ていましたが、違いはわかりませんでした。{}対()を明確にしていただきありがとうございます。
スターソン2018

2

方法は

$ > g++ -lpthread perform.c -o per
$ > time ./per

出力は>>

real    0m0.014s
user    0m0.010s
sys     0m0.002s

-lphtreadまたは-oタグを使用する必要はありません。time受け入れられた答えがよりよく説明するコマンドを使用する必要があるだけです。
デニス

7
これは例でした。つまり、私のperform.cにはスレッドが含まれているため、-lpthreadが必要で、簡単なIDには-o perです。
Robel Sharma

0

おそらく単純な方法の1つ(さまざまなユーザーのニーズを満たさない可能性があります)は、シェルPROMPTを使用することです。これは、場合によっては便利な単純なソリューションです。以下の例のように、bashプロンプト機能を使用できます。

PS1 = '[\ t \ u @ \ h] \ $'をエクスポート 

上記のコマンドを実行すると、シェルプロンプトが次のように変更されます。

[HH:MM:SSユーザー名@ホスト名] $ 

コマンドを実行する(またはEnterキーを押す)たびにシェルプロンプトに戻るたびに、プロンプトに現在の時刻が表示されます。

注:
1)次のコマンドを入力する前にしばらく待った場合は、この時間を考慮する必要があることに注意してください。つまり、シェルプロンプトに表示される時間は、コマンドを入力したときではなく、シェルプロンプトが表示されたときのタイムスタンプです。一部のユーザーは、Enterキーを押して、次のコマンドの準備ができる前に、新しいタイムスタンプ付きの新しいプロンプトを表示することを選択します。
2) bashプロンプトを変更するために使用できる他の使用可能なオプションと修飾子があります。詳細については(man bash)を参照してください。


プログラムが実行される時点ではなく、プログラムが実行される期間。
ジェノ陳
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.