В вашем упрощенном примере у вас есть два процесса (ваша оболочка и кошка ), пытающихся читать с «ведомой» стороны tty. В результате один процесс получает некоторые символы, другой получает другие.
Что вы подразумеваете под «перенаправлением ввода с одного [терминала] на другой»? В вашей реальной ситуации, какие процессы пытаются читать с каждого терминала? Что вы хотите сделать с записанным вводом, как только он у вас будет? Что именно вы на самом деле пытаетесь достичь?
Для меня «перенаправление ввода-вывода процесса, запущенного в GDB» больше похоже на повторное открытие stdin / stdout / stderr внутри процесса, который уже запущен.
Вы можете изменить stdin / stdout / stderr запущенного процесса с (среди прочего ) GDB. Ответ «Перенаправить STDERR / STDOUT процесса ПОСЛЕ того, как он запущен с использованием командной строки?» Показывает, как это можно сделать. Вы хотели бы заменить tty путь /dev/null
в ответе, и вы, вероятно, хотите обрабатывать stdin, но метод все еще применим.
Вы должны быть в состоянии заставить ваш упрощенный пример работать надежно, но я не уверен, что он делает то, что вы на самом деле хотите делать (имейте в виду, что псевдотерминал на самом деле представляет собой пару устройств, как два конца двунаправленной трубы; но весь ваш пример это взаимодействует с "ведомыми" половинками).
Ключ к исправлению вашего примера - заставить всех, кроме одного конкурирующего процесса (временно) прекратить чтение из терминала. Если, как в вашем примере, у вас есть оболочка, запущенная на той стороне, с которой вы хотите захватывать данные, тогда вы можете сделать что-то вроде этого:
( 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 )