Script to quickly test all keyboard keys

6,111

Solution 1

Try replacing your grep line with an awk script that flushes its output.

xev | \
awk '/state 0x.*, keycode / { print $4; fflush() }' | \
while read keycode ; do
    # etc.
done

Solution 2

After some more trial-and-error, Google and man, this version works as I expected:

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

Create your list based on xev output (I hastefully used xev | grep keycode, keyboard smash and regex replacements on a text editor) and replace it.

Share:
6,111

Related videos on Youtube

mdrg
Author by

mdrg

Updated on September 18, 2022

Comments

  • mdrg
    mdrg over 1 year

    I need to check some notebooks for bad keyboard keys, and so I'd like to speed that up as much as possible.

    I found nothing for this specific task, so my idea is a script that reads the pressed keys and knows all the keyboard keys, so I can bash them quickly and it reports which ones are not pressed yet. I suppose I could accomplish that with either showkey or xev, grepping the output:

    xev | grep keysym
    

    Sample output:

    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,
    

    The readable keysym is quite useful, but I keed to test keycodes, as they do not change as modifier keys are switched on/off (caps lock, num lock). I'm new to bash, so I'm putting something together. This is best result so far:

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

    While I used grep it was only printing the output when I closed xev and it wouldn't kill it at the end too. The awk suggestion from @200_success solved these issues, but it does not print the output immediatelly: it takes 5-6 keystrokes for the output to be "flushed". How can I fix that?

    Note: I know that this script would require a different list of keys for each different model of keyboard, but this is OK, as I only have a couple models to test.


    Edit 1: I edited the question with my latest script code.

    Edit 2: script updated according to @200_success suggestion.

    • Rahul Patil
      Rahul Patil over 10 years
      array should like this list=( a b c d e f Shift_L Return ) isn't it ?
    • Rahul Patil
      Rahul Patil over 10 years
    • mdrg
      mdrg over 10 years
      @Rahul After some testing, I have a nearly functional script. I edited the question with it.
  • mdrg
    mdrg over 10 years
    Great! I could say it's done, but I was wondering why is it taking so many keystrokes to print the output, like that 'flush' is not working. If I press 'b', it takes 5-6 other keystrokes for the Pressed 56:b to appear.
  • mdrg
    mdrg over 10 years
    Found it: awk -W interactive. Thanks for your help, it was essential.