You can do it using strace.
Using strace
you can spy what is being written to file-descriptor 1, which is the stdout file descriptor. Here is an example:
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'
You may want to improve the filter, but that would be another question. We have the output, but now need to tidy it.
:WARNING: This solution has some limitations, see comments below. It will not always work, your mileage may vary.
Test:
Put this program (below) in file hello
, and chmod +x hello
#!/bin/bash
while true
do
echo -en "hello\nworld\n"
done
This one in hello1
and chmod +x hello1
#!/bin/bash
dir=$(dirname $0)
$dir/hello >/dev/null
This one in hello2
and chmod +x hello2
#!/bin/bash
dir=$(dirname $0)
$dir/hello1 >/dev/null
then run with ./hello2 >/dev/null
,
then find pid of process hello and type pid_of_process_you_want_to_see_stdout_of=xyz
where xyz is the pid of hello,
then run line at top.
How it works.
When hello is run, bash forks, redirects fd 1 to /dev/null
, then execs hello.
Hello sends output to fd1 using system call write(1, …
.
Kernel receives system call write(1, …
, sees that fd 1 is connected to /dev/null
and …
We then run strace (system-call trace) on hello, and see that it is calling write(1, "hello\nworld\n")
The rest if the line above is just selecting the appropriate line of the trace.