Перенаправить ввод с одного терминала на другой

17484
Niki Yoshiuchi

Я sshed в linux box, и я использую dvtm и bash (хотя я также пробовал это с Gnu screen и bash). У меня есть два терминала, текущий / dev / pts / 29 и / dev / pts / 130. Я хочу перенаправить ввод с одного на другой.

Из того, что я понимаю, в / dev / pts / 130 я могу набрать:

cat </dev/pts/29 

И затем, когда я набираю / dev / pts / 29, символы, которые я печатаю, должны появиться в / dev / pts / 130. Однако в конечном итоге все остальные символы, которые я печатаю, перенаправляются. Например, если я наберу «привет», я получу это:

/dev/pts/29 | /dev/pts/130  $ | $ cat </dev/pts/29 $ el | hlo 

Это действительно разочаровывает, так как мне нужно сделать это, чтобы перенаправить ввод-вывод процесса, запущенного в GDB (я пробовал запустить run / dev / pts / # и установить inferior-tty / dev / pts / #, и оба результата привели к вышеупомянутое поведение). Я что-то не так делаю, или это ошибка в bash / screen / dvtm?

7

1 ответ на вопрос

8
Chris Johnsen

В вашем упрощенном примере у вас есть два процесса (ваша оболочка и кошка ), пытающихся читать с «ведомой» стороны 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 ) 
Моей целью было запустить процесс в GDB, но взаимодействовать с процессом в другом терминале. Это было вызвано тем, что я настроил pyclewn и при запуске в терминале он перенаправляет процесс 'io в / dev / null, делая невозможным взаимодействие с ним. Однако я только что понял, что я идиот, так как я могу просто подключить GDB к процессу, запущенному в отдельном терминале, полностью обойдя мою проблему. Niki Yoshiuchi 14 лет назад 0
Я тоже искал это (отладка проклятий с проклятиями). Это заслуживает отдельного объяснения. Сохраните старый stdin, перезагрузите старый stdin при выходе и лучше всего небуферизованный ввод. Во всяком случае, это не работает идеально на Ubuntu. Сброс необходим при выходе, но использования man должно быть достаточно, чтобы настроить его, отлично! albfan 10 лет назад 0

Похожие вопросы