1. 程式人生 > 實用技巧 >Shell和Python獲取鍵盤事件

Shell和Python獲取鍵盤事件

Shell和Python可以說是Linux環境中很常用的指令碼語言了,可以方便地實現運維、測試等等自動化,減輕人的負擔。
很多時候,指令碼也需要和使用者進行簡單的互動,例如讀取鍵盤輸入。響應鍵盤事件和讀取輸入還是不同的。響應鍵盤事件指的是判斷哪個按鍵被按下,使用者按下某一按鍵後立即響應,例如按下q鍵立即退出程式。而讀取輸入則一般是使用者輸入一行後,按下回車,則程式讀入這一行字串。
讀取輸入比較常用,在Shell中可以使用read,在Python中可以使用input()或者sys.stdin.readline()等。
如果需要實現對使用者按下鍵盤按鍵的響應,可以通過以下方式實現。

Shell

Shell中可以用read

實現按鍵檢測(直譯器使用bash)。
read -rsN1 input
上述程式碼的含義是獲取鍵盤按鍵,並存放到input中。其中read的引數含義如下:

  • -r:禁用轉義字元。
  • -s:安靜模式,不將輸入顯示出來。例如按下按鍵A後,字母A不會顯示在命令列裡。
  • -N1:嚴格讀取一個字元後結束,換行符也算一個字元。

這樣就可以獲取鍵盤按下的按鍵資訊了。例如,使用者按下W、S、A、D四個按鍵後,顯示前(Forward)後(Backward)左(Left)右(Right),按下Q鍵退出,程式碼如下:

while true; do
    read -rsN1 input
    if [[ "$input" == "w" ]]; then
        echo "Forward"
    elif [[ "$input" == "s" ]]; then
        echo "Backward"
    elif [[ "$input" == "a" ]]; then
        echo "Left"
    elif [[ "$input" == "d" ]]; then
        echo "Right"
    elif [[ "$input" == "q" ]]; then
        echo "Quit!"
        break
    else
        continue
    fi
done

上面的程式碼也可以獲取按下回車鍵的事件。不過如果要判斷按下的按鍵是回車鍵,不能直接用if [[ "$input" == "\n" ]]; then這樣判斷,而是要利用echo -e進行轉義:

if [[ "$input" == `echo -e "\n"` ]]; then
        echo "You pressed enter!"
fi

Python

在Python中獲取鍵盤事件,可以使用keyboard模組。
pip install keyboard或者pip3 install keyboard

安裝該模組。同樣實現前面例子的功能,程式碼如下:

import keyboard

while True:
    if keyboard.is_pressed('w'):
        print('Forward')
    elif keyboard.is_pressed('s'):
        print('Backward')
    elif keyboard.is_pressed('a'):
        print('Left')
    elif keyboard.is_pressed('d'):
        print('Right')
    elif keyboard.is_pressed('enter'):  # if key 'enter' is pressed 
        print('You pressed enter!')
    elif keyboard.is_pressed('q'):
        print('Quit!')
        break

不過shell和python對於是否顯示輸入的處理不太一樣。使用shell指令碼時,鍵盤按下的按鍵內容是不會顯示的(因為使用了-s選項)。而使用python時,程式執行過程中會在輸出中顯示你按下的按鍵。而且如果是在命令列中執行這個指令碼,指令碼退出後,你按下的按鍵又會在命令列裡顯示,並且被命令列讀取一遍,甚至執行(如果按下一些按鍵之後按下了回車),感覺不太優雅。例如,如果在python指令碼執行過程中,你恰好依次按下了D、A、T、E鍵(小寫)和回車,那麼程式退出後,命令列真的會讀取date和回車,然後執行date,打印出日期和時間。