如何使用空白鍵停止 Bash 腳本?

如何使用空白鍵停止 Bash 腳本?

我正在開發一個用 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+ ctrap 'stty "$settings"' EXIT負責在腳本退出時恢復舊設定。

筆記:

  • 在陷阱的程式碼中,stty $settingsstty "$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 }'

禮貌地瑞奇

相關內容