将当前按下的键打印到标准输出并逐行读取它们

将当前按下的键打印到标准输出并逐行读取它们

我想知道键盘上按下了哪些键并将信息打印到标准输出。

可以做到这一点的工具是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

解决方案:

我用过洛尼克斯的解决方案并将其包含到我的简单键盘中: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

答案1

尝试showkey使用以下命令将输出设置为非缓冲stdbuf命令:

stdbuf -o0 showkey -a | cat -

将在按下按键时显示输出,而不是缓冲一行。

stdbufstdin可以调整、stdout和的缓冲stderr,将它们设置为没有任何,行缓冲, 或者块缓冲,具有可选择的块大小。非常便利。

答案2

它会缓冲,因为您的终端设置为面向行的行规则。你需要stty raw。尝试这个:

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

但这仅适用于单字节按键。LC_ALL=C如果输入有可能包含多字节 kepresses,那么首先执行此操作可能是个好主意。一个更复杂的例子可能看起来更像这样:

{   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

相关内容