Bash – Redirect stderr from an already running script

bashio-redirectionstdout

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?

Best Answer

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.

Related Question