In your simplified example, you have two processes (your shell, and the cat) trying to read from the “slave” side of the tty. The result is that one process gets some of the characters, the other gets the others.
What do you mean by “redirect the input from one [terminal] to the other”? In your real situation, what processes are trying to read from each terminal? What do you want to do with your captured input once you have it? What, exactly, are you actually trying to accomplish?
To me, “redirect the io of a process running in gdb” seems more like re-opening stdin/stdout/stderr inside a process that is already running.
You can change stdin/stdout/stderr of a running process with (among other things) GDB. An answer to “Redirect STDERR / STDOUT of a process AFTER it’s been started, using command line?” shows how it can be done. You would want to substitute a tty pathname for /dev/null
in the answer, and you probably want to handle stdin, too, but the technique is still applicable.
You should be able to make your simplified example work robustly, but I am not convinced that it does what you actually want to do (keep in mind that a pseudo terminal is actually a pair of devices, like two ends of a bidirectional pipe; but all your example does it interact with the ‘slave’ halves).
The key to fixing your example is to get all but one of the competing process to (temporarily) stop read from the terminal. If, like your example, you have a shell running on the side from which you would like to capture data, then you can do something like this:
(
s="$(stty -g)"
exec 3<&0
trap 'stty "$s" 0<&3;exit' 0 INT QUIT
cat <<EOM
In some other terminal, run the command
cat <$(tty)
Press ^C or ^\ to quit.
EOM
stty raw isig brkint susp '' dsusp ''
while true; do sleep 3600; done </dev/null
)
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
Best Answer
One solution is changing the init system, so a getty process gets a tty and invokes your script. Your script might then initialize a named pipe (aka fifo) and redirect stdin to it.
Then you can login via ssh and read from that pipe.