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
,打印出日期和時間。