2017-04-04 4 views
3

PS0とPS1変数(プロンプトコマンドが実行される前後でevalされている)でコードを実行すると、実行中の各コマンドの時刻を記録し、プロンプトに表示します。そのような何か:PS0とPS1を使って各bashコマンドの実行時間を表示する

[email protected] ~/tmp 
$ sleep 1 

[email protected] ~/tmp 1.01s 
$ 

このような何かがうまくいかないので、私はすぐに、PS0に記録時間で立ち往生してしまった:

PS0='$(START=$(date +%s.%N))' 

私は理解しているように、START割り当てはサブで起こります外殻には見えません。どのようにこれにアプローチしますか?

答えて

1

私はパズルとしてこれを取り、私の不可解な結果を表示する:

まず、私は時間測定いじっ。 date +%s.%N(これまで私が気付いていなかった)は、私が始めた場所でした。残念ながら、bashの算術評価は浮動小数点をサポートしていないようです。したがって、私は何か別のものを選んだ:

$ START=$(date +%s.%N) 

$ awk 'BEGIN { printf("%fs", '$(date +%s.%N)' - '$START') }' /dev/null 
8.059526s 

$ 

これは時間差を計算するのに十分である。

次に、あなたがすでに説明したことを確認しました。サブシェル呼び出しはシェル変数の使用を防ぎます。したがって、私はどこにサブタイトルがグローバルであるが、複数のインタラクティブシェルで同時に使用できるように十分なローカルの開始時刻をどこに格納できるか考えました。私の解決策はtempです。ファイル(/tmp)。ユニークな名前を付けるために、私はこのパターンを思いついた:/tmp/$USER.START.$BASHPID

$ date +%s.%N >/tmp/$USER.START.$BASHPID ; \ 
> awk 'BEGIN { printf("%fs", '$(date +%s.%N)' - '$(cat /tmp/$USER.START.$BASHPID)') }' /dev/null 
cat: /tmp/ds32737.START.11756: No such file or directory 
awk: cmd. line:1: BEGIN { printf("%fs", 1491297723.111219300 -) } 
awk: cmd. line:1:           ^syntax error 

$ 

くそー!もう一度私はサブシェルの問題に閉じ込められています。

$ INTERACTIVE_BASHPID=$BASHPID 

$ date +%s.%N >/tmp/$USER.START.$INTERACTIVE_BASHPID ; \ 
> awk 'BEGIN { printf("%fs", '$(date +%s.%N)' - '$(cat /tmp/$USER.START.$INTERACTIVE_BASHPID)') }' /dev/null 
0.075319s 

$ 

次のステップ::PS0PS1でこの一緒にフィドルこの周りに来て、私は別の変数を定義しました。同様のパズル(SO: How to change bash prompt color based on exit code of last command?)で、私はすでに "引用地獄"を習得しました。したがって、私は再びそれを行うことができるはずです:

$ PS0='$(date +%s.%N >"/tmp/${USER}.START.${INTERACTIVE_BASHPID}")' 

$ PS1='$(awk "BEGIN { printf(\"%fs\", "$(date +%s.%N)" - "$(cat /tmp/$USER.START.$INTERACTIVE_BASHPID)") }" /dev/null)'"$PS1" 
0.118550s 
$ 

Ahh。それは働き始める。したがって、唯一の問題は - INTERACTIVE_BASHPIDの初期化のための正しいスタートアップスクリプトを見つけることです。私は~/.bashrcを見つけました。これはこれに適しているようですが、私は過去にいくつかの個人的なカスタマイズのためにすでに使っていました。

# command duration puzzle 
INTERACTIVE_BASHPID=$BASHPID 
date +%s.%N >"/tmp/${USER}.START.${INTERACTIVE_BASHPID}" 
PS0='$(date +%s.%N >"/tmp/${USER}.START.${INTERACTIVE_BASHPID}")' 
PS1='$(awk "BEGIN { printf(\"%fs\", "$(date +%s.%N)" - "$(cat /tmp/$USER.START.$INTERACTIVE_BASHPID)") }" /dev/null)'"$PS1" 

3行目(dateコマンド)は別の問題を解決するために追加されました: -

だから、一緒にすべてを入れて、これらは私が私の~/.bashrcに追加行があります。それをコメントアウトして新しいインタラクティブなbashを起動して、その理由を調べてください。

私は​​に上記の行を追加したバッシュと私のcygwinのxtermのスナップショット: Snapshot of my cygwin xterm with the "tuned" bash prompt

注:

  1. 私はむしろ、「深刻な生産よりもパズルの解決策として、これを考えます"ソリューション。私は、この種の時間測定はそれ自身に多くの時間を費やすと確信しています。 timeコマンドは、より良い解決法を提供するかもしれません:SE: How to get execution time of a script effectively?。しかし、これは素敵な講義でした...

  2. このコードは、あなたの/tmpディレクトリに小さなファイルが増えていくことを忘れないでください。 /tmpを随時クリーンアップするか、クリーンアップに適切なコマンドを追加してください(例:~/.bash_logout)。

関連する問題