wiki:Internal/OpenFlow/miscUnix

Version 1 (modified by akoshibe, 12 years ago) ( diff )

*Nix related tidbits…

This is a page on various tools and techniques related to *nix administration, programming, disaster recovery - basically, odds and ends that come in handy once every so often. Anything based on a link is reiterated just for completeness, and just in case a link dies.

Redirecting the output of a live process.

source: http://etbe.coker.com.au/2008/02/27/redirecting-output-from-a-running-process/

Say that you have a running process whose outputs are either being piped to /dev/null or a terminal that you can't get a hold of, but you'd like to be able to see its output. Conversely, you may want to redirect something's output to /dev/null. You can force the process to change its output using gdb, the GNU debugger. This is a powerful tool that allows you to attach to a live process and inspect and manipulate the contents of its address space.

Here I have a script that I had backgrounded but is still outputting to my terminal (annoying). I will redirect the program's output to a file.

  1. Find the PID of your process. Mine is called arrival_collector.rb, so I look for it using ps.
    # ps -ef | grep collector
    root     17793 11276  0 18:39 pts/1    00:00:00 ruby arrival_collector.rb -r a,h,ee,f,wknd1,wknd2 -s scott,busch_a,pubsafs,foodsci,scott,scott -v
    

/proc/ shows that its STDOUT is my terminal, /dev/pts/1:

# ls -l /proc/17793/fd
total 0
lrwx------ 1 root root 64 2012-02-19 18:45 0 -> /dev/pts/1
lrwx------ 1 root root 64 2012-02-19 18:45 1 -> /dev/pts/1
lrwx------ 1 root root 64 2012-02-19 18:40 2 -> /dev/pts/1
lrwx------ 1 root root 64 2012-02-19 18:45 3 -> socket:[1566783742]
  1. Attach to the process with GDB.
    # gdb -p [PID] [path/to/executable]
    

It wil spew a bunch of output but eventually give you a prompt:

# gdb -p 17793 /opt/grailrtls/grail3_ruby/grail3protocols/arrival_collector.rb
GNU gdb (GDB) 7.2-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
...
Loaded symbols for /lib/libnss_files.so.2
0xb78c7424 in __kernel_vsyscall ()
(gdb) 
  1. Close STDOUT:
    (gdb) p close(1)
    $1 = 0
    
  1. Point STDOUT to a file. Like in the link, I will use creat() to point STDOUT to a log file in /tmp/. creat() takes the path to the file and its permissions as the two arguments.
    (gdb) p creat("/tmp/output.log", 0600)
    $2 = 1
    
  1. Exit gdb. Choose yes when asked if you want to quit.
    (gdb) quit
    A debugging session is active.
    
            Inferior 1 [process 17793] will be detached.
    
    Quit anyway? (y or n) y
    Detaching from program: /usr/bin/ruby1.8, process 17793
    

Now when you check /proc/ you should see that your STDOUT is directed att the file you created:

# ls -l /proc/17793/fd
total 0
lrwx------ 1 root root 64 2012-02-19 18:45 0 -> /dev/pts/1
lrwx------ 1 root root 64 2012-02-19 18:45 1 -> /tmp/output.log
lrwx------ 1 root root 64 2012-02-19 18:40 2 -> /dev/pts/1
lrwx------ 1 root root 64 2012-02-19 18:45 3 -> socket:[1566783742]

you can confirm this with tail -f (or the fact that your program has stopped outputting to terminal).

Note: See TracWiki for help on using the wiki.