[one-liner]: Redirecting an Already Running Program’s STDOUT to a File using dupx

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.

This entry was posted in centos, fedora, linux, one-liner, rhel, shell, Syndicated, sysadmin, tips & tricks. Bookmark the permalink.

Comments are closed.