我正在開發一個用 Bash 編寫的魔術方塊秒錶,我想透過按下空白鍵來停止它,因為當你必須盡快終止它時Ctrl+是不可行的。C
那麼有沒有辦法只用空白鍵來停止程式呢?
我抬頭看著命令kill
,我不明白。
秒錶部分程式碼如下:
TMP0=$(date +%s%N)
while true; do
TMP1=$(date +%s%N)
DTMP=$(($TMP1-$TMP0))
printf "\r$(($DTMP/1000000000)).${DTMP:(-9):2}"
done
答案1
Ctrl當您按+時,您的終端將 SIGINT 傳送到前台進程組c。您可以將其配置為對任何角色執行此操作,但您希望在腳本退出時恢復舊設定。
#!/bin/bash
settings="$(stty -g)"
trap 'stty "$settings"' EXIT
stty intr ' '
TMP0=$(date +%s%N)
while true; do
TMP1=$(date +%s%N)
DTMP=$(($TMP1-$TMP0))
printf '\r%s' "$(($DTMP/1000000000)).${DTMP:(-9):2}"
done
settings="$(stty -g)"
儲存舊設定;stty intr ' '
使終端做出反應Space而不是Ctrl+ c;trap 'stty "$settings"' EXIT
負責在腳本退出時恢復舊設定。
筆記:
在陷阱的程式碼中,stty $settings
比stty "$settings"
.這是“總是引用「規則。引用可以防止分詞和檔案名稱產生(通配符),但某些實作stty
可能需要分詞,因此變數不能被引用。為了避免檔案名稱產生有害的副作用,規格需要stty -g
產生一個不會觸發此功能的字串。編輯:這是 POSIX 規範中的一個缺陷。上面的程式碼已被修復。
如果出現問題並且您發現自己處於Space仍產生 SIGINT 的互動式 shell 中,則需要手動呼叫
stty intr ^C
。命令中有空格,但請記住,您仍然可以透過按Ctrl+鍵入文字空格字元v Space。我使用是因為我認為靜態格式和動態資料比您使用的動態格式更
printf '\r%s' …
符合“哲學” 。printf
「Space而不是Ctrl+ c」表示當Space變得特殊時,Ctrl+c不再是特殊的。你可以稱之為缺陷,因為用戶會期望Ctrl+c保持特別。不過,同時使兩者變得特殊並不是一件小事,我認為這不能透過配置終端來完成。
這個替代版本幾乎在任何鍵上都會停止,而Ctrl+c照常工作:
#!/bin/bash
while read -r -t 0.001; do :; done # dump the buffer
TMP0=$(date +%s%N)
until read -r -n 1 -t 0.001; do
TMP1=$(date +%s%N)
DTMP=$(($TMP1-$TMP0))
printf '\r%s' "$(($DTMP/1000000000)).${DTMP:(-9):2}"
done
echo
要使其僅對您做出反應,Space您需要檢查已讀取的內容:
…
until read -r -n 1 -t 0.001 && [ "$REPLY" = ' ' ]; do
…
Space請注意,停止腳本的機制現在與Ctrl+ 的c工作方式非常不同。
答案2
如果你不需要秒錶,畢竟你只是想知道最終花費的時間,你可以使用:
time read -r -n 1
它會給你一個類似的輸出:
time read -r -n 1
real 1m30.909s
user 0m0.000s
sys 0m0.000s
並停止幾乎任何擊鍵(類似於卡米爾的使用方式read
)
或者如果您只想要時間部分:
{ time read -r -n 1; } 2>&1 | grep real | awk '{ print $2 }'
禮貌地瑞奇