Bash

不閱讀時Shell腳本循環

  • September 2, 2019

我試圖找出在終端不是活動視窗時使用鍵盤快捷鍵停止正在執行的腳本的最佳方法。

這使我了解了使用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為任何有用的東西),我原以為您所做的測試永遠不會是真的,並且腳本將無限期地執行。可能是您的腳本中有未顯示的程式碼?

在任何情況下,您都不需要readfrom evtest。相反,您可以使用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我們需要整行匹配(沒有子字元串,如如果字元串在開始和結束處都錨定)。

如果你想對grepor施加超時evtest,你可以使用timeoutGNU coreutils。

引用自:https://unix.stackexchange.com/questions/538642