Script para testar rapidamente todas as teclas do teclado

14

Preciso verificar alguns blocos de anotações em busca de teclas defeituosas no teclado e, portanto, gostaria de acelerar isso o máximo possível.

Não encontrei nada para esta tarefa específica; portanto, minha ideia é um script que leia as teclas pressionadas e conheça todas as teclas do teclado, para que eu possa bater rapidamente nelas e relate quais ainda não foram pressionadas. Suponho que eu poderia conseguir isso com um showkeyou outro xev, saudando a saída:

xev | grep keysym

Saída de amostra:

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,

O keyym legível é bastante útil, mas eu preciso testar os códigos de chave, pois eles não mudam à medida que as teclas modificadoras são ativadas / desativadas (caps lock, num lock). Eu sou novo no bash, então estou montando algo. Este é o melhor resultado até agora:

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

Enquanto eu usava grep, estava apenas imprimindo a saída quando eu fechei xeve não a mataria no final também. A awksugestão do @ 200_success resolveu esses problemas, mas não imprime a saída imediatamente: são necessárias 5-6 pressionamentos de tecla para que a saída seja "liberada". Como posso consertar isso?

Nota: Eu sei que esse script exigiria uma lista diferente de teclas para cada modelo diferente de teclado, mas tudo bem, pois só tenho alguns modelos para testar.


Editar 1: editei a pergunta com o meu código de script mais recente.

Edição 2: script atualizado de acordo com a sugestão @ 200_success.

mdrg
fonte
3
matriz deve gostar disso, list=( a b c d e f Shift_L Return )não é?
Rahul Patil
1
paste.ubuntu.com/6115446
Rahul Patil
@ Raul sim, o que eu postei é uma string. Meus testes trabalharam primeiro com ele, então eu postei de qualquer maneira. Mas certamente, uma lista é mais apropriada para isso. Obrigado pelo seu snippet.
mdrg
@Rahul Após alguns testes, tenho um script quase funcional. Eu editei a pergunta com ele.
precisa saber é o seguinte

Respostas:

5

Tente substituir sua greplinha por um awkscript que libere sua saída.

xev | \
awk '/state 0x.*, keycode / { print $4; fflush() }' | \
while read keycode ; do
    # etc.
done
200_success
fonte
Ótimo! Eu poderia dizer que está feito, mas fiquei me perguntando por que estão demorando tantas teclas para imprimir a saída, como se 'flush' não estivesse funcionando. Se eu pressionar 'b', são necessárias 5-6 outras teclas para Pressed 56:bque apareça.
mdrg
Verificou-se: awk -W interactive. Obrigado pela sua ajuda, foi essencial.
mdrg
1

Após mais algumas tentativas e erros, o Google e manesta versão funcionam como eu esperava:

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

Crie sua lista com base na xevsaída (usei com pressa xev | grep keycode, esmagamento do teclado e substituições de regex em um editor de texto) e substitua-a.

mdrg
fonte