Вы можете сделать это, используя strace.
Используя strace
вы можете следить за тем, что записывается в дескриптор файла 1, который является дескриптором файла stdout. Вот пример:
strace -p $pid_of_process_you_want_to_see_stdout_of 2>&1 | \
sed -re 's%^write\(1,[[:blank:]](.*),[[:blank:]]*[0-9]+\)[[:blank:]]*=[[:blank:]]*[0-9]+%\1%g'
Вы можете улучшить фильтр, но это был бы другой вопрос. У нас есть выход, но теперь нужно привести его в порядок.
: ПРЕДУПРЕЖДЕНИЕ. Это решение имеет некоторые ограничения, см. Комментарии ниже. Это не всегда будет работать, ваш пробег может отличаться.
Тестовое задание:
Поместите эту программу (ниже) в файл hello
, и chmod +x hello
#!/bin/bash
while true
do
echo -en "hello\nworld\n"
done
Это в hello1
и chmod +x hello1
#!/bin/bash
dir=$(dirname $0)
$dir/hello >/dev/null
Это в hello2
и chmod +x hello2
#!/bin/bash
dir=$(dirname $0)
$dir/hello1 >/dev/null
затем запустите с помощью ./hello2 >/dev/null
, затем найдите pid процесса hello и введите pid_of_process_you_want_to_see_stdout_of=xyz
где xyz - это pid hello, затем запустите строку сверху.
Как это устроено.
Когда запускается hello, bash-форки перенаправляют fd 1 в /dev/null
, а затем исполняют hello.
Hello отправляет вывод в fd1, используя системный вызов write(1, …
.
Ядро получает запись системного вызова write(1, …
, видит, что fd 1 подключен к /dev/null
и…
Затем мы запускаем strace (системный вызов trace) в hello и видим, что он вызывает write(1, "hello\nworld\n")
. Остальное, если строка выше просто выбирает соответствующую строку трассировки.