Прикрепите к выходу процесса для просмотра

112

Как мне «прикрепить» консоль / представление терминала к выходным данным приложения, чтобы я мог видеть, что он может говорить?

Как мне отключиться от вывода приложения, не убивая приложение?

Обычно, если вы запускаете болтливое приложение из командной строки, вы получаете все виды замечательных результатов. Однако предположим, что у меня запущено особенно болтливое программирование, такое как KINO, и я хочу просматривать его вывод в любой момент без перезапуска через командную строку. Я не могу; по крайней мере, я не знаю как.

Агитан
источник
1
У вас есть символ отладки в вашем процессе? Работает ли он в производственной среде? И если да, нужно ли вам, чтобы это НИКОГДА не приостанавливалось?
Ив Бом,
Когда у меня возникают проблемы со стабильностью программ конечных пользователей, таких как kino (сбои и гашение звука), я хочу знать, как / почему они разбились, чтобы я мог работать над их исправлением. Это не программа, которую я разрабатываю, а техника, которую я хотел бы знать для устранения неполадок. Я попробую ваше предложение ниже.
aggitan

Ответы:

18

Здесь есть несколько вариантов. Один из них - перенаправить вывод команды в файл, а затем использовать «хвост» для просмотра новых строк, которые добавляются в этот файл в реальном времени.

Другой вариант - запустить вашу программу внутри «экрана», который представляет собой своего рода текстовое приложение Терминала. Сеансы экрана могут быть присоединены и отсоединены, но номинально предназначены только для использования одним и тем же пользователем, поэтому, если вы хотите поделиться ими между пользователями, это большая головная боль в заднице.

Дон Верве
источник
1
«Здесь есть несколько вариантов. Один - перенаправить вывод команды в файл, а затем использовать« хвост »для просмотра новых строк, которые добавляются в этот файл в реальном времени». Можно ли это сделать с уже запущенными приложениями?
aggitan 03
2
Вам, вероятно, понадобится tail -f $ log_file, чтобы получить вывод, как он записан в файле. Кроме того, нет, я не знаю, как сделать это с уже запущенным приложением.
Вархан 03
@aggitan: Нет. Для существующих приложений вам придется перезапустить их, потому что они уже привязали свой ввод-вывод к управляющему терминалу.
Дон Верве,
290

Думаю, у меня есть более простое решение. Просто найдите каталог, имя которого соответствует PID, который вы ищете, в псевдофайловой системе, доступной по /procпути. Итак, если у вас запущена программа с идентификатором 1199, cdв нее:

$ cd /proc/1199

Затем найдите fdкаталог под

$ cd fd

Этот fdкаталог содержит объекты файловых дескрипторов, которые использует ваша программа (0: stdin, 1: stdout, 2: stderr), и только tail -fтот, который вам нужен - в данном случае stdout):

$ tail -f 1
солодка
источник
9
Я не смог использовать, так tailкак в моем случае вывод был перенаправлен на другой процесс для ввода, но moreпоказал мне текущие данные.
Ωmega
10
Один из самых захватывающих постов на этом сайте!
Роберт
2
moreу меня работает. ubuntu 14.04 в процессе узла
Ши-Мин Ли
1
Это не работает для меня с java-процессом, который вызывает System.out.println. В / proc / [pid] / fd / 1 нет вывода вообще
Ник
1
Пытался создать репродукцию, используя нижеприведенное, но безуспешно: `` docker run -it --name container1 ubuntu bash -c -i "COUNT = 0; while true; do echo Keep the dance floor beat; (( COUNT ++)); sleep 1; echo \ "Count is: \ $ {COUNT} \"; done; " `` В другом терминале: `` docker exec -it container1 tail -f / proc / 1 / fd / 1 ''
JacobWuzHere
54

Я искал то же самое и обнаружил, что вы можете:

strace -ewrite -p $PID

Это не совсем то, что вам нужно, но довольно близко.

Я попробовал перенаправить вывод, но у меня это не сработало. Может быть, потому что процесс записывал в сокет, я не знаю.

Пол Шельтема
источник
спасибо, он работает, но вывод усечен, например, для ping: write (1, "64 байта из 1.0.0.1: icmp_seq =" ..., 56) = 56
izy
8

Как мне «прикрепить» консоль / представление терминала к выходным данным приложения, чтобы я мог видеть, что он может говорить?

Что касается этого вопроса, я знаю, что можно поймать вывод, даже если вы не запускали команду sceen перед запуском processus.

Хотя я никогда не пробовал, но нашел интересную статью, в которой объясняется, как это сделать с помощью GDB (и без перезапуска процесса).

перенаправление вывода из запущенного процесса

В принципе:

  1. Проверьте список открытых файлов вашего процесса благодаря / proc / xxx / fd
  2. Присоедините свой процесс к GDB
  3. Пока он приостановлен, закройте интересующий вас файл, вызвав функцию close () (вы можете любую функцию вашего процесса в GDB. Я подозреваю, что вам нужны символы отладки в вашем процессе ..)
  4. Откройте новый файл, вызвав функцию create () или open (). (Посмотрите комментарии в конце, вы увидите, что люди предлагают использовать dup2 (), чтобы гарантировать, что тот же дескриптор будет использоваться)
  5. Отключите процесс и дайте ему поработать.

Кстати, если вы используете ОС Linux на i386, в комментариях говорится о лучшем инструменте для перенаправления вывода на новую консоль: «retty» . Если да, рассмотрите возможность его использования.

Ив Бом
источник
6

Для меня это сработало:

  1. Войдите в систему как владелец процесса (даже если вам rootотказано в разрешении)

    ~$ su - process_owner
    
  2. Следите за дескриптором файла, как упоминалось во многих других ответах.

    ~$ tail -f /proc/<process-id>/fd/1 # (0: stdin, 1: stdout, 2: stderr)
    
Акки
источник
2

Я хотел удаленно наблюдать за процессом обновления yum, который выполнялся локально, поэтому, хотя, вероятно, были более эффективные способы сделать это, вот что я сделал:

watch cat /dev/vcsa1

Очевидно, вы захотите использовать vcsa2, vcsa3 и т. Д., В зависимости от того, какой терминал использовался.

Пока мое окно терминала было той же ширины, что и терминал, на котором выполнялась команда, я мог видеть моментальный снимок их текущего вывода каждые две секунды. Другие команды, рекомендованные в другом месте, не очень хорошо работали в моей ситуации, но эта сработала.

RedScourge
источник