Monday, February 27, 2012

Redirecting Output of already Running Process I

Every process has opened stdin, stdout and stderr files by default. Those files are opened when process is created. If standard files redirected to any file(devices are also file type in linux) you can check it on "/proc/$PID/fd/" directory where $PID is process id. Sometimes we may need to redirect output to another file. In that case we can do this with gdb. On the other hand, If you need this for your own application you can add redirecting standard files as a feature with a small code.
We can test gdb method with tail command. Open /var/log/messages with tail command and send output to /dev/null device.

      root@work:~# tail -f /var/log/messages > /dev/null &
      [1] 32312

We have a background process with pid "32287" and standard output have been redirected to /dev/null device. 

       root@work:~# ls -l /proc/32312/fd/1
       l-wx------ 1 root root 64 Feb 27 18:23 /proc/32312/fd/1 -> /dev/null

After sometimes we want to write message logs to another file. We will use gdb to change stdout file. First we attach gdb to our process with pid:

       gdb -p 32312

In gdb command line, we will close stdout file which fd is "1" and then we will create our new file and it will be smallest suitable file descriptor which means "1". Then we will need to detach and quit gdb.

       (gdb) p close(1)
       $1 = 0
       (gdb) p creat("/tmp/mylog.txt", 0600)
       $2 = 1
       (gdb) detach
       Detaching from program: /usr/bin/tail, process 32312
       (gdb) q

Let's check redirected output file of our process again and see the our new file:
       root@work:~# ls -l /proc/32312/fd/1
       l-wx------ 1 root root 64 Feb 27 18:23 /proc/32312/fd/1 -> /tmp/mylog.txt