Skrypt do szybkiego testowania wszystkich klawiszy klawiatury

14

Muszę sprawdzić niektóre notebooki pod kątem złych klawiszy klawiatury, dlatego chciałbym przyspieszyć to tak bardzo, jak to możliwe.

Nie znalazłem nic do tego konkretnego zadania, więc moim pomysłem jest skrypt, który odczytuje naciśnięte klawisze i zna wszystkie klawisze klawiatury, dzięki czemu mogę je szybko rozwalić i zgłasza, które nie zostały jeszcze naciśnięte. Podejrzewam, że mógłbym to osiągnąć za pomocą albo, showkeyalbo xevgrepowania wyjścia:

xev | grep keysym

Przykładowe dane wyjściowe:

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,

Czytelny klawisz jest dość użyteczny, ale staram się przetestować kody, ponieważ nie zmieniają się, ponieważ klawisze modyfikujące są włączane / wyłączane (Caps Lock, Num Lock). Jestem nowy w bash, więc składam coś razem. To jak dotąd najlepszy wynik:

#!/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

Podczas gdy ja używałam grep, drukowałam wyjście dopiero po zamknięciu xevi nie zabiłoby to również na końcu. awkSugestia od @ 200_success rozwiązać te problemy, ale nie drukuje wyjście immediatelly: trwa 5-6 naciśnięcia klawiszy na wyjściu jest „przepłukać”. Jak mogę to naprawić?

Uwaga: Wiem, że ten skrypt wymagałby innej listy klawiszy dla każdego modelu klawiatury, ale jest to w porządku, ponieważ mam tylko kilka modeli do przetestowania.


Edycja 1: Zredagowałem pytanie moim najnowszym kodem skryptowym.

Edycja 2: skrypt zaktualizowany zgodnie z sugestią @ 200_success.

mdrg
źródło
3
tablica powinna to lubić, list=( a b c d e f Shift_L Return )prawda?
Rahul Patil,
1
paste.ubuntu.com/6115446
Rahul Patil
@Rahul tak, to, co opublikowałem, to ciąg. Moje testy właśnie z tym działały, więc i tak opublikowałem. Ale z pewnością lista jest bardziej odpowiednia do tego. Dziękuję za Twój fragment.
mdrg
@Rahul Po kilku testach mam prawie funkcjonalny skrypt. Zredagowałem to pytanie.
mdrg

Odpowiedzi:

5

Spróbuj zastąpić swój grepwiersz awkskryptem, który usuwa dane wyjściowe.

xev | \
awk '/state 0x.*, keycode / { print $4; fflush() }' | \
while read keycode ; do
    # etc.
done
200_sukces
źródło
Świetny! Mógłbym powiedzieć, że jest skończony, ale zastanawiałem się, dlaczego tak wiele naciśnięć klawiszy powoduje wydrukowanie wyniku, tak jakby „flush” nie działał. Jeśli naciśniesz „b”, pojawi się 5-6 innych naciśnięć klawiszy Pressed 56:b.
mdrg
Okazało się, że: awk -W interactive. Dzięki za pomoc, to było niezbędne.
mdrg
1

Po kilku próbach i błędach Google i manta wersja działa zgodnie z oczekiwaniami:

#!/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

Utwórz listę na podstawie xevdanych wyjściowych (używam pośpiesznie xev | grep keycode, zamiany klawiatury i wyrażeń regularnych w edytorze tekstu) i zamień ją.

mdrg
źródło