|  | 1 | = *Nix related tidbits... = | 
          
            |  | 2 | 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. | 
          
            |  | 3 | Anything based on a link is reiterated just for completeness, and just in case a link dies. | 
          
            |  | 4 |  | 
          
            |  | 5 | == Redirecting the output of a live process. == | 
          
            |  | 6 | source: http://etbe.coker.com.au/2008/02/27/redirecting-output-from-a-running-process/ | 
          
            |  | 7 |  | 
          
            |  | 8 | 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. | 
          
            |  | 9 |  | 
          
            |  | 10 | 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. | 
          
            |  | 11 |  | 
          
            |  | 12 | 1. Find the PID of your process. Mine is called arrival_collector.rb, so I look for it using `ps`. | 
          
            |  | 13 | {{{ | 
          
            |  | 14 | # ps -ef | grep collector | 
          
            |  | 15 | 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 | 
          
            |  | 16 | }}} | 
          
            |  | 17 |  | 
          
            |  | 18 | /proc/ shows that its STDOUT is my terminal, /dev/pts/1: | 
          
            |  | 19 | {{{ | 
          
            |  | 20 | # ls -l /proc/17793/fd | 
          
            |  | 21 | total 0 | 
          
            |  | 22 | lrwx------ 1 root root 64 2012-02-19 18:45 0 -> /dev/pts/1 | 
          
            |  | 23 | lrwx------ 1 root root 64 2012-02-19 18:45 1 -> /dev/pts/1 | 
          
            |  | 24 | lrwx------ 1 root root 64 2012-02-19 18:40 2 -> /dev/pts/1 | 
          
            |  | 25 | lrwx------ 1 root root 64 2012-02-19 18:45 3 -> socket:[1566783742] | 
          
            |  | 26 | }}} | 
          
            |  | 27 |  | 
          
            |  | 28 | 2. Attach to the process with GDB. | 
          
            |  | 29 | {{{ | 
          
            |  | 30 | # gdb -p [PID] [path/to/executable] | 
          
            |  | 31 | }}} | 
          
            |  | 32 |  | 
          
            |  | 33 | It wil spew a bunch of output but eventually give you a prompt: | 
          
            |  | 34 | {{{ | 
          
            |  | 35 | # gdb -p 17793 /opt/grailrtls/grail3_ruby/grail3protocols/arrival_collector.rb | 
          
            |  | 36 | GNU gdb (GDB) 7.2-ubuntu | 
          
            |  | 37 | Copyright (C) 2010 Free Software Foundation, Inc. | 
          
            |  | 38 | ... | 
          
            |  | 39 | Loaded symbols for /lib/libnss_files.so.2 | 
          
            |  | 40 | 0xb78c7424 in __kernel_vsyscall () | 
          
            |  | 41 | (gdb) | 
          
            |  | 42 | }}} | 
          
            |  | 43 |  | 
          
            |  | 44 | 3. Close STDOUT: | 
          
            |  | 45 | {{{ | 
          
            |  | 46 | (gdb) p close(1) | 
          
            |  | 47 | $1 = 0 | 
          
            |  | 48 | }}} | 
          
            |  | 49 |  | 
          
            |  | 50 | 4. 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. | 
          
            |  | 51 | {{{ | 
          
            |  | 52 | (gdb) p creat("/tmp/output.log", 0600) | 
          
            |  | 53 | $2 = 1 | 
          
            |  | 54 | }}} | 
          
            |  | 55 |  | 
          
            |  | 56 | 5. Exit gdb. Choose yes when asked if you want to quit. | 
          
            |  | 57 | {{{ | 
          
            |  | 58 | (gdb) quit | 
          
            |  | 59 | A debugging session is active. | 
          
            |  | 60 |  | 
          
            |  | 61 | Inferior 1 [process 17793] will be detached. | 
          
            |  | 62 |  | 
          
            |  | 63 | Quit anyway? (y or n) y | 
          
            |  | 64 | Detaching from program: /usr/bin/ruby1.8, process 17793 | 
          
            |  | 65 | }}} | 
          
            |  | 66 |  | 
          
            |  | 67 | Now when you check /proc/ you should see that your STDOUT is directed att the file you created: | 
          
            |  | 68 | {{{ | 
          
            |  | 69 | # ls -l /proc/17793/fd | 
          
            |  | 70 | total 0 | 
          
            |  | 71 | lrwx------ 1 root root 64 2012-02-19 18:45 0 -> /dev/pts/1 | 
          
            |  | 72 | lrwx------ 1 root root 64 2012-02-19 18:45 1 -> /tmp/output.log | 
          
            |  | 73 | lrwx------ 1 root root 64 2012-02-19 18:40 2 -> /dev/pts/1 | 
          
            |  | 74 | lrwx------ 1 root root 64 2012-02-19 18:45 3 -> socket:[1566783742] | 
          
            |  | 75 | }}} | 
          
            |  | 76 |  | 
          
            |  | 77 | you can confirm this with `tail -f` (or the fact that your program has stopped outputting to terminal). |