Bash
不閱讀時Shell腳本循環
我試圖找出在終端不是活動視窗時使用鍵盤快捷鍵停止正在執行的腳本的最佳方法。
這使我了解了使用
cat /dev/input/eventX
( 其中 X 是對應於擊鍵事件的數字)觀看鍵盤事件然後,我了解了一種工具,該工具
evtest
將一直執行,直到中斷以人類可讀的格式列印出事件(擊鍵)。這是我到目前為止管理的腳本,但它沒有按預期工作。在一個完美的解決方案中,使用者可以隨時按 Key_Space 來停止腳本,但我認為這裡不可能。所以我的解決方法是在循環開始時給他們一個 2 秒的視窗。
#!/bin/bash exitCase='*type 1 (EV_KEY), code 57 (KEY_SPACE)*' while [ true ] do evtest /dev/input/eventX | read -s -t 2 line if [ "$line" = "$exitCase" ] then echo caught event exit 0 else echo loop doing stuff fi done
問題是腳本將執行一次而不循環,有沒有更好的方法來做到這一點?或者我怎樣才能調整我的腳本循環,直到它看到與退出案例匹配的輸入?
我認為另一個潛在的問題是一次擊鍵會列印出多行,所以也許我需要一個
evtest /dev/input/eventX | while read line
?但是在嘗試之後,我只能讓它循環事件,而不是在等待它們時。
由於管道的右側
evtest | read line
在單獨的子外殼中執行(因此永遠不會設置line
為任何有用的東西),我原以為您所做的測試永遠不會是真的,並且腳本將無限期地執行。可能是您的腳本中有未顯示的程式碼?在任何情況下,您都不需要
read
fromevtest
。相反,您可以使用grep
(這也可以解決您最後提到的“潛在問題”):#!/bin/sh exitCase='*type 1 (EV_KEY), code 57 (KEY_SPACE)*' while true; do if evtest /dev/input/eventX | grep -q -Fx -e "$exitCase"; then echo caught event break else echo loop doing stuff fi done
一旦
evtest
產生與$exitCase
. 告訴它安靜的-q
選項grep
(我們只對退出狀態感興趣),-F
我們確保grep
將$exitCase
字元串作為字元串而不是正則表達式進行比較,並且-x
我們需要整行匹配(沒有子字元串,如如果字元串在開始和結束處都錨定)。如果你想對
grep
or施加超時evtest
,你可以使用timeout
GNU coreutils。