Keyboard

將目前按下的鍵列印到標準輸出並逐行讀取

  • July 18, 2014

我想知道我的鍵盤上按下了哪些鍵並將資訊列印到標準輸出。

可以做到這一點的工具是showkey. 但是,如果我想將數據傳遞showkeyread

while read line; do
 echo "$line" | otherprog
done <`showkey -a`

或者

showkey -a | while read line; do
 echo "$line" | otherprog
done

然後showkey等到輸入總和 140 個字元,然後將緩衝的資訊發送到read.

showkey -a逐行列印按下的鍵,沒有任何緩衝。

  1. 為什麼會緩衝?
  2. 如何避免這種緩衝,以便我可以showkey真正逐行讀取輸出?
  3. 有替代方案showkey嗎?
  4. 有沒有可以直接讀取按鍵的文件?
  5. 將數據傳遞給的正確方法是什麼read

解決方案:

我使用了 lornix 的解決方案並將其包含在我的簡單鍵盤鍵盤中:D!

stdbuf -o0 showkey -a | while read line; do
 perl -e 'print sprintf "%030s\n",shift' "$line" | aplay &> /dev/null &
done

雷射版:

#!/bin/bash
MP3=(); for i in mp3/*.mp3; do MP3+=("$i"); done
NMP3=${#MP3[@]}
stdbuf -o0 showkey -a 2>/dev/null | while read line; do
   [ -z "$line" ] || ! [[ $line =~ ^[0-9] ]] && continue
   NUM="$(echo "$line" | awk '{print $2}')"
   mplayer "${MP3[$(($NUM % $NMP3))]}" &>/dev/null &
done

在同一文件夾中,將一些雷射 mp3 文件下載到名為mp3.

嘗試showkey使用以下命令將輸出設置為非緩衝stdbuf

stdbuf -o0 showkey -a | cat -

將在按鍵被按下時顯示輸出,而不是緩沖一行。

stdbuf可以調整 和 的緩衝,stdin將它們設置為noneline bufferedblock buffered,並具有可選擇的塊大小。非常便利。stdout``stderr

它會緩衝,因為您的終端設置為面向行的行規。你需要stty raw. 試試這個:

state=$(stty -g) 
key=$( (stty raw ; dd bs=1 count=1; stty $state) </dev/tty 2>/dev/null) 

但這僅適用於單字節按鍵。LC_ALL=C如果輸入有可能包含多字節鍵,那麼先做可能是個好主意。一個更複雜的例子可能看起來更像這樣:

{   exit=$(printf '\003')
   tty_state=$(stty -g)
   stty raw istrip
   while key=$(
       dd bs=1 count=1
   ) ; do : "${key:=
}";     printf " %03o %03d %#x\n\r" \
           "'$key" "'$key" "'$key"
       [ -z "${key#"$exit"}" ] && {
           stty "$tty_state"
           break
       }
   done 2>/dev/null
} </dev/tty

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