-
-
Save phoenix24/782505 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ctrl-z | |
bg | |
touch /tmp/stdout | |
touch /tmp/stderr | |
gdb -p $! | |
# In GDB | |
p dup2(open("/tmp/stdout", 1), 1) | |
p dup2(open("/tmp/stderr", 1), 2) | |
detach | |
quit | |
# Back in shell | |
disown | |
logout |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
!/bin/bash
THIS=$0
ARGS=$@
name=$(basename $THIS)
usage () {
$name -o /tmp/test $ !
$name -n 0:/tmp/test $ !
cat <<EOF
Usage: $name: redirect input/output/error of a running process
Two ways to run this program:
$name [-q][-o ] [-e ] [-i ] [-n : ]
or simply:
$name [-q]
The first form files specified in -o, -e, and -i options will become
standard output, standard error, and standard input. At least one
option must be specified, or second form will be assumed.
For example, using Bash syntax:
bash -c 'sleep 1m && echo "rise and shine"' &
The same with explicit stdout descriptor number (1) using -n option:
bash -c 'sleep 1m && echo "rise and shine"' &
In the second form, current in/out/err are remapped into the process.
$name $ ! >>/tmp/test
For example, using Bash syntax:
bash -c 'sleep 1m && echo "rise and shine"' &
These examples should be equivalent (i.e. -o foo will append to file foo,
if it already exists) with respect to stdout, but in the second stdin and
stderr are remapped as well.
Option (-n) allows explicit specification of file descriptors.
It can be given multiple times, e.g.:
$name -n 0:/tmp/stdin -n 1:/tmp/stdout -n 2:/tmp/stderr PID
is equivalent to, using Bash syntax:
$name 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 specify filename of the new standard input
-o specify filename of the new standard output
-e specify filename of the new standard error
-n : specify descriptor number and filename to remap to
-q be quiet
-h this help
EOF
}
warn () {
echo "$name: $@" >&2
}
XXX add multiple -n option
quiet="no"
nopt=""
while getopts "ho:e:i:qn:" opt; do
case $opt in
( o ) stdout=$OPTARG; ;;
( e ) stderr=$OPTARG; ;;
( i ) stdin=$OPTARG; ;;
( n ) nopt="$nopt $OPTARG"; ;;
( q ) quiet="yes"; ;;
( * ) usage; exit 0; ;;
esac
done
shift $((OPTIND-1))
if [ $# != 1 ]; then
usage
exit 1
fi
if [ -n "$stdout" ] && ! 2>/dev/null : >> $stdout ; then
warn "Cannot write to (-o) $stdout"
exit 1
fi
if [ -n "$stderr" ] && ! 2>/dev/null : >> $stderr ; then
warn "Cannot write to (-e) $stderr"
exit 1
fi
if [ -n "$stdin" ] && ! 2>/dev/null : >> $stdin ; then
warn "Cannot write to (-i) $stdin"
exit 1
fi
fds=""
if [ -n "$nopt" ]; then
for n_f in $nopt; do
n=${n_f%%:}
f=${n_f##:}
if [ -n "${n//[0-9]/}" ] || [ -z "$f" ]; then
warn "Error parsing descriptor (-n $n_f)"
exit 1
fi
if ! 2>/dev/null : >> $f; then
warn "Cannot write to (-n $n_f) $f"
exit 1
fi
fds="$fds $n"
fns[$n]=$f
done
fi
if [ -z "$stdout" ] && [ -z "$stderr" ] && [ -z "$stdin" ] && [ -z "$nopt" ]; then
#second invocation form: dup to my own in/err/out
[ -e /proc/$$/fd/0 ] && stdin=$(readlink /proc/$$/fd/0)
[ -e /proc/$$/fd/1 ] && stdout=$(readlink /proc/$$/fd/1)
[ -e /proc/$$/fd/2 ] && stderr=$(readlink /proc/$$/fd/2)
if [ -z "$stdout" ] && [ -z "$stderr" ] && [ -z "$stdin" ]; then
warn "Could not determine current standard in/out/err"
exit 1
fi
fi
PID=$1
if ! 2>/dev/null kill -0 $PID; then
warn "Error accessing PID $PID"
exit 1
fi
if [ "$quiet" != "yes" ]; then
msg_stdout="Remaining standard output of $PID is redirected to $stdout\n"
msg_stderr="Remaining standard error of $PID is redircted to $stderr\n"
fi
gdb_cmds () {
local _name=$1
local _mode=$2
local _desc=$3
local _msgs=$4
local _len
}
trap '/bin/rm -f $GDBCMD' EXIT$PID is remapped to $ {fns[$n]}\n"
GDBCMD=$(mktemp /tmp/gdbcmd.XXXX)
{
#Linux file flags (from /usr/include/bits/fcntl.sh)
O_RDONLY=00
O_WRONLY=01
O_RDWR=02
O_CREAT=0100
O_APPEND=02000
echo "#gdb script generated by running '$0 $ARGS'"
echo "attach $PID"
gdb_cmds "$stdin" $((O_RDONLY)) 0 "$msg_stdin"
gdb_cmds "$stdout" $((O_WRONLY|O_CREAT|O_APPEND)) 1 "$msg_stdout"
gdb_cmds "$stderr" $((O_WRONLY|O_CREAT|O_APPEND)) 2 "$msg_stderr"
for n in $fds; do
msg="Descriptor $n of
gdb_cmds ${fns[$n]} $((O_RDWR|O_CREAT|O_APPEND)) $n "$msg"
done
#echo "quit"
} > $GDBCMD
if gdb -batch -n -x $GDBCMD >/dev/null </dev/null; then
[ "$quiet" != "yes" ] && echo "Success" >&2
else
warn "Remapping failed"
fi
cp $GDBCMD /tmp/gdbcmd
rm -f $GDBCMD