Background
Recently I came across this really cool UNIX tool called dupx. I was looking for a way to connect to a program’s STDOUT and STDERR after I had already started it. This was a long running, think 30+ hours job, and I didn’t want to have to stop and restart it. As is the case with UNIX/Linux, there’s an app for that.
Solution
Dupx isn’t an actual program per say, it’s actually a shell script that eases the task of using the real workhorse, GDB that allows you to connect to an already running program. GDB is the command line GNU Debugger for C & C++ applications but it can do a lot more. In our case, GDB is being used by dupx to attach to our program/script’s process id (PID), and then manipulating the already running programs environment to repoint STDOUT, STDERR, and even STDIN to new locations.
Here’s an example where I’ve started up a program without redirecting its output, STDOUT to anywhere specific:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# ex. 1: sleep for 10 seconds, then echo a msg. # get the current time % date Wed Jan 25 21:25:07 EST 2012 # run a job % bash -c 'sleep 10 && echo "rise and shine"' & [1] 14992 # NOTE: pid 14992, output from job % rise and shine # wait 10 secs, hit return a couple of times % % [1]+ Done bash -c 'sleep 10 && echo "rise and shine"' # note that program ran for > 10 secs. % date Wed Jan 25 21:25:29 EST 2012 |
Here’s an example where I’ve started up a program without redirecting its output, and then ran dupx to redirect this program’s STDOUT to my shell’s STDOUT:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# ex. 2: sleep for 10 seconds, then echo a msg., use dupx to hijack STDOUT and # redirect to my shell's STDOUT # get the current time % date Wed Jan 25 21:47:42 EST 2012 # run a job % bash -c 'sleep 10 && echo "rise and shine"' & [1] 15663 # redirect pid 15663 STDOUT to shell's STDOUT % dupx 15663 Remaining standard output of 15663 is redirected to /dev/pts/9 Remaining standard error of 15663 is redircted to /dev/pts/9 Success # output was redirected from program's STDOUT to our terminals STDOUT (/dev/pts/9 is our terminal) % rise and shine # wait 10 secs, hit return a couple of times % % [1]+ Done bash -c 'sleep 10 && echo "rise and shine"' # note that program ran for > 10 secs. % date Wed Jan 25 21:48:02 EST 2012 |
Finally here’s an example where I’ve redirected an already running program’s STDOUT to a file, /tmp/test:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# ex. 3: sleep for 10 seconds, then echo a msg., use dupx to hijack STDOUT and redirect # to a file, /tmp/test # get the current time % date Wed Jan 25 21:56:23 EST 2012 # run a job % bash -c 'sleep 10 && echo "rise and shine"' & [1] 15946 # redirect pid 15946 STDOUT to /tmp/test % dupx -o /tmp/test 15946 Remaining standard output of 15946 is redirected to /tmp/test Success # wait 10 secs, hit return a couple of times % % [1]+ Done bash -c 'sleep 10 && echo "rise and shine"' # note that program ran for > 10 secs. % date Wed Jan 25 21:56:47 EST 2012 # confirm program's output was redirected to /tmp/test |
Dupx can do a fair amount more. For example it can individually redirect STDOUT, STDERR, and STDIN to different locations.
1 |
% dupx [-q][-o <outfile>] [-e <errorfile>] [-i <inputfile>] [-n <fd>:<filename> ] <pid> |
Here are some more usage examples:
1 2 3 4 5 6 7 8 |
# redirect STDOUT to one file, STERR to another % dupx -o /tmp/test1 -e /tmp/test2 1234 # redirect STDOUT to one file, STDERR to another (using file descriptor numbers instead) % dupx -n 1:/tmp/test1 -n 2:/tmp/test2 1234 # redirect STDIN, STDOUT, & STDERR % dupx -n 0:/tmp/test0 -n 1:/tmp/test1 -n 2:/tmp/test2 1234 |
Here are the rest of the options for dupx:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Option (-n) allows explicit specification of file descriptors. It can be given multiple times, e.g.: dupx -n 0:/tmp/stdin -n 1:/tmp/stdout -n 2:/tmp/stderr PID is equivalent to, using Bash syntax: dupx PID </tmp/stdin >/tmp/stdout 2>/tmp/stderr All files specified in (-n) option are opened in read/write & append mode. Summary of options: -i <stdin> specify filename of the new standard input -o <stdout> specify filename of the new standard output -e <stderr> specify filename of the new standard error -n <fd>:<filename> specify descriptor number and filename to remap to -q be quiet -h this help |
The following are available from my local yum repository:
They’re also availble from the dpux website here.
References
links
local copies
NOTE: For further details regarding my one-liner blog posts, check out my one-liner style guide primer.