Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

185
LINES

< > BotCompany Repo | #1033366 // dupx

Document

1  
#!/bin/bash
2  
3  
THIS=$0
4  
ARGS=$@
5  
name=$(basename $THIS)
6  
7  
usage () {
8  
    cat <<EOF
9  
Usage: $name: redirect input/output/error of a running process
10  
Two ways to run this program:
11  
    $name [-q][-o <outfile>] [-e <errorfile>] [-i <inputfile>] [-n <fd>:<filename> ] <pid>
12  
or simply:
13  
    $name [-q] <pid>
14  
The first form files specified in -o, -e, and -i options will become
15  
standard output, standard error, and standard input.  At least one
16  
option must be specified, or second form will be assumed.
17  
For example, using Bash syntax:
18  
    bash -c 'sleep 1m && echo "rise and shine"' &
19  
    $name -o /tmp/test \$!
20  
The same with explicit stdout descriptor number (1) using -n option:
21  
    bash -c 'sleep 1m && echo "rise and shine"' &
22  
    $name -n 0:/tmp/test \$!
23  
    
24  
In the second form, current in/out/err are remapped into the process.
25  
For example, using Bash syntax:
26  
    bash -c 'sleep 1m && echo "rise and shine"' &
27  
    $name \$! >>/tmp/test
28  
These examples should be equivalent (i.e. -o foo will append to file foo,
29  
if it already exists) with respect to stdout, but in the second stdin and
30  
stderr are remapped as well.
31  
32  
Option (-n) allows explicit specification of file descriptors.
33  
It can be given multiple times, e.g.:
34  
    $name -n 0:/tmp/stdin -n 1:/tmp/stdout -n 2:/tmp/stderr PID
35  
is equivalent to, using Bash syntax:
36  
    $name PID </tmp/stdin >/tmp/stdout 2>/tmp/stderr
37  
All files specified in (-n) option are opened in read/write & append mode.
38  
39  
Summary of options:
40  
    -i <stdin>  specify filename of the new standard input
41  
    -o <stdout> specify filename of the new standard output
42  
    -e <stderr> specify filename of the new standard error
43  
    -n <fd>:<filename> specify descriptor number and filename to remap to
44  
    -q          be quiet
45  
    -h          this help
46  
47  
EOF
48  
}
49  
50  
51  
warn () {
52  
    echo "$name: $@" >&2
53  
}
54  
55  
# XXX add multiple -n option
56  
quiet="no"
57  
nopt=""
58  
while getopts "ho:e:i:qn:" opt; do
59  
    case $opt in
60  
        ( o ) stdout=$OPTARG; ;;
61  
        ( e ) stderr=$OPTARG; ;;
62  
        ( i ) stdin=$OPTARG; ;;
63  
  ( n ) nopt="$nopt $OPTARG"; ;;
64  
        ( q ) quiet="yes"; ;;
65  
        ( * ) usage; exit 0; ;;
66  
    esac
67  
done
68  
69  
shift $((OPTIND-1))
70  
71  
72  
if [ $# != 1 ]; then
73  
    usage
74  
    exit 1
75  
fi
76  
77  
if [ -n "$stdout" ] && ! 2>/dev/null : >> $stdout ; then
78  
    warn "Cannot write to (-o) $stdout"
79  
    exit 1
80  
fi
81  
82  
if [ -n "$stderr" ] && ! 2>/dev/null : >> $stderr ; then
83  
    warn "Cannot write to (-e) $stderr"
84  
    exit 1
85  
fi
86  
87  
if [ -n "$stdin" ] && ! 2>/dev/null : >> $stdin ; then
88  
    warn "Cannot write to (-i) $stdin"
89  
    exit 1
90  
fi
91  
92  
fds=""
93  
if [ -n "$nopt" ]; then
94  
    for n_f in $nopt; do
95  
  n=${n_f%%:*}
96  
  f=${n_f##*:}
97  
  if [ -n "${n//[0-9]/}" ] || [ -z "$f" ]; then 
98  
      warn "Error parsing descriptor (-n $n_f)"
99  
      exit 1
100  
  fi
101  
  if ! 2>/dev/null : >> $f; then
102  
      warn "Cannot write to (-n $n_f) $f"
103  
      exit 1
104  
  fi
105  
  fds="$fds $n"
106  
  fns[$n]=$f
107  
    done
108  
fi
109  
if [ -z "$stdout" ] && [ -z "$stderr" ] && [ -z "$stdin" ] && [ -z "$nopt" ]; then
110  
    #second invocation form: dup to my own in/err/out
111  
    [ -e /proc/$$/fd/0 ] &&  stdin=$(readlink /proc/$$/fd/0)
112  
    [ -e /proc/$$/fd/1 ] && stdout=$(readlink /proc/$$/fd/1)
113  
    [ -e /proc/$$/fd/2 ] && stderr=$(readlink /proc/$$/fd/2)
114  
    if [ -z "$stdout" ] && [ -z "$stderr" ] && [ -z "$stdin" ]; then
115  
  warn "Could not determine current standard in/out/err"
116  
  exit 1
117  
    fi
118  
fi
119  
120  
PID=$1
121  
if ! 2>/dev/null kill -0 $PID; then
122  
    warn "Error accessing PID $PID"
123  
    exit 1
124  
fi
125  
126  
if [ "$quiet" != "yes" ]; then
127  
    msg_stdout="Remaining standard output of $PID is redirected to $stdout\n"
128  
    msg_stderr="Remaining standard error of $PID is redircted to $stderr\n"
129  
fi
130  
131  
gdb_cmds () {
132  
    local _name=$1
133  
    local _mode=$2
134  
    local _desc=$3
135  
    local _msgs=$4
136  
    local _len
137  
138  
    [ -w "/proc/$PID/fd/$_desc" ] || _msgs=""
139  
    if [ -d "/proc/$PID/fd" ] && ! [ -e "/proc/$PID/fd/$_desc" ]; then
140  
  warn "Attempting to remap non-existent fd $n of PID ($PID)"
141  
    fi
142  
143  
    [ -z "$_name" ] && return
144  
145  
    echo "set \$fd=open(\"$_name\", $_mode)"
146  
    echo "set \$xd=dup($_desc)"
147  
    echo "call dup2(\$fd, $_desc)"
148  
    echo "call close(\$fd)"
149  
    if  [ $((_mode & 3)) ] && [ -n "$_msgs" ]; then
150  
        _len=$(echo -en "$_msgs" | wc -c)
151  
        echo "call write(\$xd, \"$_msgs\", $_len)"
152  
    fi
153  
    echo "call close(\$xd)"
154  
}
155  
156  
trap '/bin/rm -f $GDBCMD' EXIT
157  
GDBCMD=$(mktemp /tmp/gdbcmd.XXXX)
158  
{
159  
    #Linux file flags (from /usr/include/bits/fcntl.sh)
160  
    O_RDONLY=00
161  
    O_WRONLY=01
162  
    O_RDWR=02 
163  
    O_CREAT=0100
164  
    O_APPEND=02000
165  
    echo "#gdb script generated by running '$0 $ARGS'"
166  
    echo "attach $PID"
167  
    gdb_cmds "$stdin"  $((O_RDONLY)) 0 "$msg_stdin"
168  
    gdb_cmds "$stdout" $((O_WRONLY|O_CREAT|O_APPEND)) 1 "$msg_stdout"
169  
    gdb_cmds "$stderr" $((O_WRONLY|O_CREAT|O_APPEND)) 2 "$msg_stderr"
170  
    for n in $fds; do
171  
  msg="Descriptor $n of $PID is remapped to ${fns[$n]}\n"
172  
  gdb_cmds ${fns[$n]} $((O_RDWR|O_CREAT|O_APPEND)) $n "$msg"
173  
    done
174  
    #echo "quit"
175  
} > $GDBCMD
176  
177  
cat $GDBCMD
178  
echo
179  
if gdb -batch -n -x $GDBCMD >/dev/null </dev/null; then
180  
    [ "$quiet" != "yes" ] && echo "Success" >&2
181  
else
182  
    warn "Remapping failed"
183  
fi
184  
#cp $GDBCMD /tmp/gdbcmd
185  
rm -f $GDBCMD

download  show line numbers   

Travelled to 2 computer(s): bhatertpkbcr, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1033366
Snippet name: dupx
Eternal ID of this version: #1033366/2
Text MD5: 65ac9705493e4d2ccbefa5218d8a645a
Author: stefan
Category:
Type: Document
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-10-25 05:48:55
Source code size: 5281 bytes / 185 lines
Pitched / IR pitched: No / No
Views / Downloads: 80 / 34
Version history: 1 change(s)
Referenced in: [show references]