Bash
Bash:將 history -a 添加到 PROMPT_COMMAND 會使最後一個命令的掛起時間計算不正確
要計算最後一個命令的掛牆時間,我使用以下程式碼(
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: history is lost after ssh connection is reset by peer: how to save the history?),在前面的程式碼(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
問題:為什麼在 make
code #2
之後添加code #1
會code #1
產生不正確的結果?怎麼修?
事件鏈(假設讀者知道什麼
${var:-someval}
有效):
你輸入一些命令。
當您按下輸入鍵時,
DEBUG
將執行陷阱。
timer_start=${timer_start:-$(timer_now)}
然後執行命令。
然後
set_prompt
被執行。
- 咩咩咩,然後
unset timer_start
- 計時器重新啟動。然後
DEBUG
在之前執行traphistory -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
陷阱。