Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I've been running a script for several days now. I redirected stdout to $HOME/mylog, but didn't redirect stderr since I thought there would be nothing on it. Suddenly thousands of lines started coming out on stderr, so I suspended the job. Is there a way I can redirect stderr to $HOME/myerr from now on, without needing to restart the script?

I have sudo access on the box and it's OS X.

Perhaps something using dtools trapping?

I cannot lose the work the script has done so far and restart it from scratch. Is there a way to "dump the in-memory objects" on disk, freeze the program, edit the variables (e.g. the file descriptors) and resume with the new context?

share|improve this question
    
possible duplicate of Redirecting/grep'ing an existing shell's STDOUT –  Gilles Aug 14 '12 at 23:52
add comment

2 Answers

up vote 10 down vote accepted

I think it is possible if you attach the process of the related interpreter to gdb. I tried it with this perl one-liner

 perl -e 'do { print "x\n"; sleep(1) } while(1)'

and it works but unfortunately not with a similar bash script.


First of all you have to figure out the PID of that process whose output you want to capture. Then start gdb in another terminal and execute the following gdb-commands

attach PID
call close(2)
call open("/abs/olu/te/path/filename", 65, 384)
detach PID

after that the whole data that is written to stderr is redirected to /abs/olu/te/path/filename, since

  • attach PID attaches the process to gdb and stops it
  • call close(2) closes the stderr filedescriptor of the process (for stdout the filedescriptor is 1)
  • call open(...) opens a new file and takes the lowest unused integer for the newly created filedescriptor and
  • detach PID continues the process

At least on my machine. The first two lines are POSIX compatible but not the third one.

The second and the third argument of open in the third line are documented in man 2 open. In my case 65 means that open should create the file and open the file write-only i.e. O_WRONLY | O_CREAT (defined in fcntl.h). The third argument tells open to create the file with read and write permission for the user i.e. S_IWUSR | S_IRUSR (defined in sys/stat.h). So maybe you have to find out appropriate values on your machine by yourself.

share|improve this answer
    
This worked so stupendously well... hats off!! –  Robottinosino Aug 19 '12 at 20:24
add comment

This is a crude answer and I hope someone else does better, but if no other ideas surface, attach gdb and force the process to make a few syscalls:

(gdb) attach 12345 # target PID
(gdb) p close(2)
(gdb) p open("errfile", O_WRONLY)
(gdb) c
share|improve this answer
    
Nifty. I wasn't aware gdb could do that. Is there any way to force it to a specific file descriptor number? Like say if FD 1 is unused, and the open() grabs FD 1? Or do you just have to call dup() a few times? –  Patrick Aug 14 '12 at 23:53
    
does p open("errfile", O_WRONLY) really work on your machine? –  user1146332 Aug 15 '12 at 0:07
    
You could stick in a p dup2(xxx, 2) and then p close(xxx) where xxx is the return value of the open. This is tricky stuff, better not use these commands on a long-running process until you're sure there's no other choice. –  Alan Curry Aug 15 '12 at 0:08
    
@user1146332 it did when I tried it because I used /dev/null as my errfile so I didn't need O_CREAT. And O_WRONLY being a macro, whether it expands or not depends on whether gdb stopped the process at a line where debugging symbols are available and the macro is defined. Injecting code into a process with gdb is dangerous and nobody just should be copying these commands without understanding them. –  Alan Curry Aug 15 '12 at 0:18
    
@AlanCurry I don't think that gdb expands macros if general debugging information is available. You have to compile the sources with special flags (see here ). Besides it is very uncommon that an arbitrary executable on your system has debugging information included (let anlone the information are extended with macro information). But i agree with you that code injection is generally not advisable, but there might be cases where you benefit. –  user1146332 Aug 15 '12 at 8:45
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.