Ubuntu – How to redirect an already running process’s stdout/stderr

processredirectstdoutUbuntu

(Running on an Ubuntu 10.04 64-bit server)

Yesterday, I made the mistake of starting a process (which I didn't realize was going to take several days to run) over SSH without using screen. I've spent all day today trying to figure out some way that I can pry the process's output from SSH's iron grasp so that I can reboot my client machine, but am not getting anywhere.

I tried using gdb and following the instructions at the bottom of this page, but when I run the first gdb command to create a file, I get an error message stating No symbol table is loaded. Use the "file" command. From what I gathered, this means I have to recompile the program whose output I'm trying to redirect, which of course is absolutely no help to me now that it's already running.

I also thought I might be able to use retty to redirect output to another terminal, but evidently it does not compile on 64-bit platforms.

How can I redirect this process's output to another terminal or to a file?

Best Answer

It looks like those instructions given for gdb are incorrect and incomplete in several ways.

First, you need to use

gdb [executablefile] [pid]

so that GDB knows what the program it's connecting to actually is. I just tested this, and it can use a stripped executable. Note that while gdb is attached to the process the process will be suspended. If this process is communicating over a network, type quickly or the network connection will probably timeout.

Second, the commands given don't explain what they're doing, and the instruction that you should cd "to a directory that you want your program to write files to" is wrong, since gdb is asking the original program to execute the creat() function. The example given will create myprog.stderr and myprog.stdout files in the Current Working Directory of the running program, not in the directory you ran gdb. Use absolute pathnames here if you don't know what that program's CWD is (or look at ls -l /proc/[pid]/cwd).

Third, running with the lack of explanation, it's important to know that the first parameter to dup2() is the file descriptor number returned by the previous creat() so if this running program had several files open you might end up with an exchange like

(gdb) call creat("/home/me/myprog.stdout",0600)
$1 = 7
(gdb) call dup2(7,1)
$2 = 1
(gdb) call creat("/home/me/myprog.stderr",0600)
$3 = 8
(gdb) call dup2(8,2)
$4 = 2

When you quit gdb, it'll ask you if you want to "quit anyway (and detach it)" the answer is yes.

Finally, bg and disown are bash builtins. If you weren't using bash, then you're on your own from here. bg moves a suspended job to the background as if it were started there using somecommand &, and disown removes the program from bash's list of active programs to SIGHUP when bash exits.