Что происходит с выходными данными процесса, который был отвергнут и потерял свой терминал?

26

Если я закрою виртуальный терминал, где был запущен какой-то процесс, вывод просто пойдет прямо /dev/nullили он каким-то образом загрязнит память? Могу ли я как-нибудь получить вывод, чтобы продолжить чтение в любой момент после этого?

[РЕДАКТИРОВАТЬ]: Итак, действительно ли момент отказа от процесса - конец моей власти контролировать его результаты?

Я также заметил, что если я отрекаюсь от остановленного процесса, сначала все кажется нормальным: он не завершается и не отображается в заданиях. Но если я выйду из системы (и я не имею в виду закрыть терминал, например, просто выйду из su), процесс завершится. Тем не менее, фоновый запущенный процесс может остаться запущенным.

rozcietrzewiacz
источник
2
Ибо «могу ли я как-нибудь получить результат»: не без грязных трюков. Но посмотрите, как я могу отречься от запущенного процесса и связать его с новой оболочкой экрана? и другие процитированные вопросы для грязных уловок (все основанные на присоединении к программе отладчика и как-то заставляя его открыть другой выходной файл).
Жиль "ТАК - перестань быть злым"
Спасибо за ссылку на этот вопрос. Это дало мне лучший ответ до сих пор! Особенно умная rettyпрограмма.
rozcietrzewiacz
1
Смотрите также этот ответ по связанному вопросу.
Стефан Гименес

Ответы:

11

Тот факт, что процесс «отвергнут», имеет значение только для интерактивной оболочки, создавшей этот процесс. Это означает, что оболочка (больше) не включает процесс в свою таблицу заданий и что SIGHUP не будет отправляться этому процессу при выходе из оболочки. Это на самом деле не связано с вашими вопросами.

О том, что происходит с выходными данными, которые отправляются на удаленный виртуальный терминал: я сам провел несколько тестов и заметил, что /dev/pts/xустройства недоступны и не будут распределяться снова, пока все файловые дескрипторы, которые указывают на них, не будут закрыты. Итак, я не вижу причины, по которой записи в удаленный терминал будут сохранены. Я предполагаю, что это даже не определено POSIX.

Насчет вывода какого-либо процесса, который пишет в терминал, я не думаю, что это возможно, даже когда терминал еще жив ». Все, что вы можете сделать, это захватить прямой ввод на терминал (т.е. нажатия клавиш или симулированные нажатия клавиш основной частью pty). Если бы процессы читали на stdin то, что записано на их терминалы, это привело бы к циклу self io для большинства процессов.

Что касается последнего замечания о завершении процесса, я действительно не знаю, что происходит, но я подозреваю довольно странное поведение с сигналами (SIGTTOU, SIGTTIN, SIGHUP или другими), связанными с основным / фоновым состоянием групп процессов, когда сеанс Лидер выходит (например su, в случае, вы упомянули).

Ответ на редактирование: Нет, что касается вывода, ничего не меняется, когда процесс отсоединяется: он все еще подключен к своему управляющему терминалу (если только он не отключился, как это делают демоны). Вы можете увидеть это, используя ps. Однако вы больше не сможете использовать fg/ bg/ jobsкоманды, предоставленные оболочкой для этого процесса. Это означает, что это может быть затруднительно для подачи данных с терминала (требуется быть в группе процессов переднего плана).

-
1. если процесс не хочет или не угнан какими-либо инструментами отладки (см. Комментарии выше).

Стефан Хименес
источник
1
Спасибо за разъяснение этого немного. На самом деле факт отказа от процесса все еще связан с моим вопросом: после отказа от процесса я, похоже, теряю способность контролировать его вывод, верно? (Даже если терминал не был закрыт.) Я отредактирую вопрос, чтобы включить этот случай.
rozcietrzewiacz
4

Просто для решения этого конкретного вопроса:

Если я закрываю виртуальный терминал, где был запущен какой-то процесс, вывод просто идет прямо в / dev / null, или он может как-то загрязнить память?

Терминал и программа (и), связанные с ним, обмениваются данными через устройство tty, читая и записывая его как файл. В частности, виртуальный терминал создает «псевдо-tty» (для краткости «pty»), а затем порождает процесс оболочки (или другой) и подключает stdin / out / err этого процесса к pty. (Детали зависят от операционной системы.)

Когда вы закрываете виртуальный терминал, виртуальный терминал закрывает свой конец соединения (pty "master"). После этого, если программа на другом конце соединения пишет в tty, возвращается ошибка, и данные никуда не уходят. Точно так же, если он читает из tty, он вернет индикатор EOF (конец файла).

Крис Пейдж
источник
Спасибо - хорошее и ясное объяснение с немного большей точки зрения программирования.
rozcietrzewiacz
3

Чтобы ответить на самую интересную часть вашего вопроса: чтобы изменить вывод работающей программы, вы должны отредактировать дескрипторы файлов. Это довольно легко сделать с GDB. Это взлом, но работает.

Видеть:

/programming/593724/redirect-stderr-stdout-of-a-process-after-its-been-started-using-command-line

Вспомогательный скрипт доступен по адресу http://users.linpro.no/ingvar/fdswap.sh.txt .

Ив Жункейра
источник
0

Благодаря комментарию Жиля, указавшему мне на этот вопрос , я узнал о программе под названием retty .

Кажется, что он использует какой-то грязный хак для повторного присоединения к (псевдотерминалу), эффективно позволяющего продолжить чтение вывода процесса - независимо от того, был ли он отринут или нет. Так что это, кажется, отвечает на большую часть первой части моего вопроса. На второй ответил Стефан .

rozcietrzewiacz
источник