Вы можете сделать это, используя 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") . Остальное, если строка выше просто выбирает соответствующую строку трассировки.