How can a process intercept stdout and stderr of another process on Linux?

Thomas Vander Stichele picture Thomas Vander Stichele · Oct 30, 2008 · Viewed 38.8k times · Source

I have some scripts that ought to have stopped running but hang around forever. Is there some way I can figure out what they're writing to STDOUT and STDERR in a readable way?

I tried, for example, to do:

$ tail -f /proc/(pid)/fd/1

but that doesn't really work. It was a long shot anyway.

Any other ideas?

strace on its own is quite verbose and unreadable for seeing this.

Note: I am only interested in their output, not in anything else. I'm capable of figuring out the other things on my own; this question is only focused on getting access to stdout and stderr of the running process after starting it.

Answer

Thomas Vander Stichele picture Thomas Vander Stichele · Oct 30, 2008

Since I'm not allowed to edit Jauco's answer, I'll give the full answer that worked for me (Russell's page relies on un-guaranteed behaviour that, if you close file descriptor 1 for STDOUT, the next creat call will open FD 1.

So, run a simple endless script like this:

import time

while True:
    print 'test'
    time.sleep(1)

Save it to test.py, run with

$ python test.py

Get the PID:

$ ps auxw | grep test.py

Now, attach gdb:

$ gdb -p (pid)

and do the fd magic:

(gdb) call creat("/tmp/stdout", 0600)
$1 = 3
(gdb) call dup2(3, 1)
$2 = 1

Now you can tail /tmp/stdout and see the output that used to go to STDOUT.