| 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). |