7

Я 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?

1 ответ1

8

В вашем упрощенном примере у вас есть два процесса (ваша оболочка и кошка), которые пытаются читать с «ведомой» стороны 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
)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .