Skript zum schnellen Testen aller Tastaturtasten

14

Ich muss in einigen Notebooks nach schlechten Tastaturtasten suchen und möchte das so weit wie möglich beschleunigen.

Ich habe für diese spezielle Aufgabe nichts gefunden, daher ist meine Idee ein Skript, das die gedrückten Tasten liest und alle Tastaturtasten kennt, damit ich sie schnell drücken kann und meldet, welche noch nicht gedrückt sind. Ich nehme an, ich könnte das mit entweder showkeyoder erreichen xev, indem ich die Ausgabe greife:

xev | grep keysym

Beispielausgabe:

state 0x10, keycode 46 (keysym 0x6c, l), same_screen YES,
state 0x10, keycode 33 (keysym 0x70, p), same_screen YES,
state 0x11, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
state 0x10, keycode 51 (keysym 0x5d, bracketright), same_screen YES,
state 0x10, keycode 36 (keysym 0xff0d, Return), same_screen YES,

Das lesbare Tastensymbol ist sehr nützlich, aber ich musste die Tastencodes testen, da sie sich nicht ändern, wenn die Modifikatortasten ein- / ausgeschaltet werden (Feststelltaste, Num-Taste). Ich bin neu im Bashing, also stelle ich etwas zusammen. Dies ist das bisher beste Ergebnis:

#!/bin/bash

function findInArray() {
    local n=$#
    local value=${!n}
    for ((i=1;i < $#;i++)) {
    if [[ ${!i} == ${value}* ]]; then
    echo "${!i}"
    return 0
    fi
    }
    echo
    return 1
}

list=( 38:a 56:b 54:c 40:d 26:e 36:Return 50:Shift_L )
xev | \
# old grep solution
# grep -Po '(?<=keycode )[0-9]+(?= \(keysym 0x)' | \
# 200_success' suggestion
awk '/state 0x.*, keycode / { print $4; fflush() }' | \
while read keycode ; 
do
  found=$(findInArray "${list[@]}" ${keycode})
  if [[ $found ]]; then
    echo Pressed $found
    list=(${list[@]/${keycode}\:*/})
    echo 'Remaining ===>' ${list[@]}
    if [[ ${#list[@]} == 0 ]]; then
      echo All keys successfully tested!
      pkill xev
      exit 0
    fi
  fi
done

Während ich es benutzte grep, druckte es nur die Ausgabe, als ich es schloss xevund es würde es am Ende auch nicht töten. Der awkVorschlag von @ 200_success behebt diese Probleme, druckt die Ausgabe jedoch nicht sofort aus: Es sind 5 bis 6 Tastenanschläge erforderlich, bis die Ausgabe "geleert" wird. Wie kann ich das beheben?

Hinweis: Ich weiß, dass für dieses Skript für jedes Tastaturmodell eine andere Liste von Tasten erforderlich ist, aber das ist in Ordnung, da ich nur ein paar Modelle zum Testen habe.


Bearbeiten 1: Ich habe die Frage mit meinem neuesten Skriptcode bearbeitet.

Edit 2: Das Skript wurde gemäß dem @ 200_Success-Vorschlag aktualisiert.

mdrg
quelle
3
Array sollte so aussehen, list=( a b c d e f Shift_L Return )nicht wahr?
Rahul Patil
1
paste.ubuntu.com/6115446
Rahul Patil
@ Rahul ja, was ich gepostet habe, ist eine Zeichenfolge. Meine Tests haben gerade erst damit geklappt, also habe ich trotzdem gepostet. Aber sicherlich ist eine Liste dafür besser geeignet. Danke für deinen Schnipsel.
mdrg
@ Rahul Nach einigen Tests habe ich ein nahezu funktionsfähiges Skript. Ich habe die Frage damit bearbeitet.
mdrg

Antworten:

5

Versuchen Sie, Ihre grepZeile durch ein awkSkript zu ersetzen , das die Ausgabe leert .

xev | \
awk '/state 0x.*, keycode / { print $4; fflush() }' | \
while read keycode ; do
    # etc.
done
200_erfolg
quelle
Groß! Ich könnte sagen, dass es fertig ist, aber ich habe mich gefragt, warum es so viele Tastenanschläge braucht, um die Ausgabe zu drucken, so dass "Flush" nicht funktioniert. Wenn ich 'b' drücke, werden 5-6 weitere Tastenanschläge benötigt, um angezeigt Pressed 56:bzu werden.
mdrg
Findet es: awk -W interactive. Vielen Dank für Ihre Hilfe, es war wichtig.
mdrg
1

Nach einigem weiteren Ausprobieren manfunktioniert Google und diese Version wie erwartet:

#!/bin/bash

function findInArray() {
  local n=$#
  local value=${!n}
  for ((i=1;i < $#;i++)) {
    if [[ ${!i} == ${value}:* ]]; then
      echo "${!i}"
      return 0
    fi
  }
  echo
  return 1
}

list=( 10:1 11:2 12:3 36:Return 37:Control_L 38:a 39:s 134:Super_R 135:Menu )
clear
echo -e "${#list[@]} keys to test\n\n${list[@]}"
xev | \
awk -W interactive '/state 0x.*, keycode / { print $4; fflush() }' | \
while read keycode ; 
do
  found=$(findInArray "${list[@]}" ${keycode})
  if [[ $found ]]; then
    clear
    echo Pressed $found
    list=(${list[@]/$found/})
    remaining=${#list[@]}
    stdbuf -oL -eL echo -e "$remaining keys remaining\n\n${list[@]}"
    if [[ $remaining == 0 ]]; then
      clear
      echo All keys successfully tested!
      pkill xev
      exit 0
    fi
  fi
done

Erstellen Sie Ihre Liste basierend auf der xevAusgabe (ich habe sie hastig verwendet xev | grep keycode, Tastatur-Smash und Regex-Ersetzungen in einem Texteditor) und ersetzen Sie sie.

mdrg
quelle