How can I read input from the hosts keyboard when connected via SSH?

This hacked together script works for me for now:

import string

from evdev import InputDevice
from select import select

keys = "X^1234567890XXXXqwertzuiopXXXXasdfghjklXXXXXyxcvbnmXXXXXXXXXXXXXXXXXXXXXXX"
dev = InputDevice('/dev/input/by-id/usb-HID_OMNIKEY_5127_CK_01010053423438303000835748112531-event-kbd')

while True:
   r,w,x = select([dev], [], [])
   for event in dev.read():
        if event.type==1 and event.value==1:
                print( keys[ event.code ] )

It uses python-evdev to read from /dev/input/foo and very dirtyly converts them to readable values.

This is what I get when I run the script and connect a card to the reader:

pi@raspberrypi ~ $ python test.py
7
6
4
3
f
a
4
6

Here is a simple hack to make it work easily until the next boot, assuming you have the required privileges.

Using the following command shows all processes running on the computer

ps -ef

To find the PID of the login/getty process from where the keyboard is currently read, we can pass the results of this function through grep.

ps -ef | grep tty

You could see something like

root     23698     1  0 18:17 ttyO0    00:00:00 /sbin/getty -L ttyO0 115200 vt102

Take note of the number in the second column - that is the PID. And the sixth column, which is where the keyboard is.

To halt that process, use the following command (substituting the number for whatever your PID is)

kill -stop 23698

Now, you can read the tty from where the keyboard keys are coming (tty is shown in the ps command)

cat /dev/ttyO0

The cat will read forever, outputting whatever is entered on the keyboard, until you kill it.

When you're done, and want to return to normal behaviour, you can resume the keyboard function with

kill -cont 23698

Of course that outlines the general idea. You could use your own program to read from the tty.


Had to do this recently for a Hackathon, so I figured I would contribute what we ended up doing.

  1. Set up autologin as root on tty1 (the main terminal where the keyboard device is dumping its input). The Arch Linux wiki entry has good instructions. Reboot to get it to log in.

  2. Copy the source of a small program known as 'ttyEcho'. One copy can be found here, but a Google search brings up many more. This program allows you to echo commands to another terminal. Compile on the target machine.

  3. Now that we can run whatever on /dev/tty1, we just can just ./ttyEcho -n /dev/tty1 'cat > buffer' to get everything input on tty1 to be added to a file. Instead of making an ever expanding file, use mkfifo buffer first to generate a special file which is just a named pipe - a FIFO queue which is backed by memory only.

  4. From your SSH session you can now just tail -f filename to watch all keyboard input on tty1. From within python, open('filename','r') and keep calling .read() or .readline() on it to get the feed of keyboard data as it comes in.

This method was great for us since it avoids keyboard scancode parsing, and keeps a nice big buffer of the data without any code.