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
)
Best Answer
The ttys are not just input/output devices. They also do a special job of acting as the controlling terminal for a session, like sending signals (Ctrl+C). /dev/ttyNN are virtual consoles, which are full screen displays on the monitor.
The terminals start from /dev/tty1. You could switch to these consoles, usually, by pressing Ctrl+Alt+Fn keys.
e.g, Ctrl+Alt+F1 takes you to the first virtual terminal. Nowadays, most of the Linux distributions run the X server from the tty1. So, pressing Ctrl+Alt+F1 may not have an effect.
Ctrl+Alt+F2 will take you to the second terminal. Usually the distributions run a login program(agetty) on the virtual terminal.
The login programs provide you a login prompt and lets you login with username/password. The init scripts decides, where all the login program will be run. So depending on that you may or may not see a login prompt on, say tty9. To go back to your GUI interface, press Ctrl+Alt+F1(as in example output above).
/dev/tty0 is a special device, which points to the current terminal. So, irrespective of where you run it from(any virtual console), anything read from/written to tty0 goes to your current terminal.
The second column in 'ps ax' also gives the controlling terminal of the program. For some programs, like daemons, you may see that the column is '?', which means they are not bound to a terminal.
/dev/pts/0 etc are psuedo-terminal devices, which are not attached to the system display. for e.g, terminal you get when you open a gnome-terminal or any other GUI terminal. These are client-server based approach where client side will be exported to programs, like bash. The data send by the program to the pseudo terminal is sent to the 'server' side (which is usually monitored by another program, like gnome-terminal). The controlling process (server side) determines what needs to be sent to the terminal, which is eventually seen by the client. These devices help you to open multiple 'GUI terminals' without any limit on your system, still providing the same old terminal like controls(ioctl(), colour setting, Sending signals [Ctrl+C] etc. ).