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

17427
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 13 лет назад 0
Я тоже искал это (отладка проклятий с проклятиями). Это заслуживает отдельного объяснения. Сохраните старый stdin, перезагрузите старый stdin при выходе и лучше всего небуферизованный ввод. Во всяком случае, это не работает идеально на Ubuntu. Сброс необходим при выходе, но использования man должно быть достаточно, чтобы настроить его, отлично! albfan 9 лет назад 0

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