最後のコマンドの停止時間を計算するには、次のコード(code #1
)を使用します。
#
# Taken from https://stackoverflow.com/a/34812608/9881330
# Slightly modified.
#
function timer_now {
date +%s%N
}
function timer_start {
timer_start=${timer_start:-$(timer_now)}
}
function timer_stop {
local delta_us=$((($(timer_now) - $timer_start) / 1000))
local us=$((delta_us % 1000))
local ms=$(((delta_us / 1000) % 1000))
local s=$(((delta_us / 1000000) % 60))
local m=$(((delta_us / 60000000) % 60))
local h=$((delta_us / 3600000000))
# Goal: always show around 3 digits of accuracy
if ((h > 0)); then timer_show=${h}h${m}m
elif ((m > 0)); then timer_show=${m}m${s}s
elif ((s >= 10)); then timer_show=${s}.$((ms / 100))s
elif ((s > 0)); then timer_show=${s}.$(printf %03d $ms)s
elif ((ms >= 100)); then timer_show=${ms}ms
elif ((ms > 0)); then timer_show=${ms}.$((us / 100))ms
else timer_show=${us}us
fi
unset timer_start
}
set_prompt () {
PS1="\n\$?"
timer_stop
PS1+=" / $timer_show"
PS1+="\n\n\[\e]0;\w\a\]\[\e[32m\]\u@\h \[\e[33m\]\w\[\e[0m\]\n\$ "
}
trap 'timer_start' DEBUG
PROMPT_COMMAND='set_prompt'
そしてそれはとてもうまくいきます:
$ gcc
gcc: fatal error: no input files
compilation terminated.
1 / 108ms
$ date
Sun Dec 27 14:53:10 RTZST 2020
0 / 89.3ms
ただし、このhistory is lost after ssh connection is reset by peer
問題を解決するには(Bash:ピアがSSH接続をリセットした後に記録が失われました。履歴を保存する方法は?)、前のコード(code #1
)の後にこのコード()を追加しましたcode #2
。
PROMPT_COMMAND="${PROMPT_COMMAND:+${PROMPT_COMMAND/%;};}history -a"
これで、最後のコマンドの停止時間が誤って計算されます(コマンドは通常、通常通りミリ秒単位で実行されます)。
$ gcc
gcc: fatal error: no input files
compilation terminated.
1 / 1.990s
$ date
Sun Dec 27 14:56:07 RTZST 2020
0 / 3.586s
質問:code #2
後に追加すると誤った結果が表示されるのはなぜcode #1
ですか?code #1
どうすれば修正できますか?
答え1
一連のイベント(読者が何がうまくいくか${var:-someval}
を知っていると仮定):
- いくつかのコマンドを入力してください。
- Enter キーを押すと
DEBUG
トラップが実行されます。timer_start=${timer_start:-$(timer_now)}
- その後、コマンドを実行します。
- それから
set_prompt
実行されました。- バラバラでは
unset timer_start
- タイマーが再起動します。
- 次に、以前
DEBUG
にトラップを実行します。history -a
timer_start=${timer_start:-$(timer_now)}
- それから
history -a
実行されました。 - 時間が経ち、コマンドを入力します。
- これにより、
DEBUG
コマンドを入力する前にトラップが実行されます。timer_start=${timer_start:-$(timer_now)}
- しかし、
timer_start
すでに設定されているので何も起こりません。
- これでコマンドが実行されます。
set_prompt
最後prompt_command
の実行以降の時間を測定するため、非常に長いですhistory -a
。
history -a
たとえば、実行前に実行したり、実行時にトラップをset_prompt
削除したりします。DEBUG