Script para probar rápidamente todas las teclas del teclado

14

Necesito verificar que algunos portátiles no tengan teclas de teclado defectuosas, por lo que me gustaría acelerarlo lo más posible.

No encontré nada para esta tarea específica, por lo que mi idea es un script que lea las teclas presionadas y conozca todas las teclas del teclado, por lo que puedo golpearlas rápidamente e informa cuáles no están presionadas todavía. Supongo que podría lograr eso con cualquiera showkeyo xev, grepping la salida:

xev | grep keysym

Salida de muestra:

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,

El keyym legible es bastante útil, pero tuve que probar los códigos de teclas, ya que no cambian ya que las teclas modificadoras se activan / desactivan (bloqueo de mayúsculas, bloqueo numérico). Soy nuevo en bash, así que estoy armando algo. Este es el mejor resultado hasta ahora:

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

Mientras lo usaba grep, solo imprimía la salida cuando cerrabaxev y no lo mataría al final también. La awksugerencia de @ 200_success resolvió estos problemas, pero no imprime la salida inmediatamente: se necesitan 5-6 pulsaciones de teclas para que la salida se "vacíe". ¿Cómo puedo arreglar eso?

Nota: Sé que este script requeriría una lista diferente de teclas para cada modelo diferente de teclado, pero esto está bien, ya que solo tengo un par de modelos para probar.


Edición 1: edité la pregunta con mi último código de script.

Edición 2: script actualizado de acuerdo con la sugerencia @ 200_success.

mdrg
fuente
3
matriz debería gustar esto, list=( a b c d e f Shift_L Return )¿no?
Rahul Patil
1
paste.ubuntu.com/6115446
Rahul Patil
@Rahul sí, lo que publiqué es una cadena. Mis pruebas simplemente funcionaron primero, así que publiqué de todos modos. Pero seguramente, una lista es más apropiada para esto. Gracias por tu fragmento.
mdrg
@Rahul Después de algunas pruebas, tengo un script casi funcional. Edité la pregunta con ella.
mdrg

Respuestas:

5

Intente reemplazar su greplínea con un awkscript que vacíe su salida.

xev | \
awk '/state 0x.*, keycode / { print $4; fflush() }' | \
while read keycode ; do
    # etc.
done
200_success
fuente
¡Excelente! Podría decir que está hecho, pero me preguntaba por qué se necesitan tantas pulsaciones de teclas para imprimir el resultado, como que 'flush' no funciona. Si presiono 'b', toma 5-6 otras pulsaciones de teclas para Pressed 56:bque aparezca.
mdrg
Encontrado: awk -W interactive. Gracias por su ayuda, fue esencial.
mdrg
1

Después de más pruebas y errores, Google y manesta versión funcionan como esperaba:

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

Cree su lista basada en la xevsalida (usé apresuradamente xev | grep keycode, reemplazos de teclado y regex en un editor de texto) y reemplácelo.

mdrg
fuente