Consulte Redireccionamiento de la salida de un proceso en ejecución .
Primero ejecuto el comando cat > foo1
en una sesión y pruebe que los datos de stdin se copian en el archivo. Luego, en otra sesión, redirijo la salida.
En primer lugar, encuentre el PID del proceso:
$ ps aux | grep cat
rjc 6760 0.0 0.0 1580 376 pts/5 S+ 15:31 0:00 cat
Ahora verifique los identificadores de archivo que tiene abiertos:
$ ls -l /proc/6760/fd
total 3
lrwx—— 1 rjc rjc 64 Feb 27 15:32 0 -> /dev/pts/5
l-wx—— 1 rjc rjc 64 Feb 27 15:32 1 -> /tmp/foo1
lrwx—— 1 rjc rjc 64 Feb 27 15:32 2 -> /dev/pts/5
Ahora ejecuta GDB:
$ gdb -p 6760 /bin/cat
GNU gdb 6.4.90-debian
[license stuff snipped]
Attaching to program: /bin/cat, process 6760
[snip other stuff that's not interesting now]
(gdb) p close(1)
$1 = 0
(gdb) p creat("/tmp/foo3", 0600)
$2 = 1
(gdb) q
The program is running. Quit anyway (and detach it)? (y or n) y
Detaching from program: /bin/cat, process 6760
El p
El comando en GDB imprimirá el valor de una expresión, una expresión puede ser una función para llamar, puede ser una llamada al sistema... Así que ejecuto un close()
llamada al sistema y paso el identificador de archivo 1, luego ejecuto un creat()
llamada al sistema para abrir un nuevo archivo. El resultado del creat()
era 1, lo que significa que reemplazó el identificador de archivo anterior. Si quisiera usar el mismo archivo para stdout y stderr o si quisiera reemplazar un identificador de archivo con algún otro número, tendría que llamar al dup2()
llamada al sistema para lograr ese resultado.
Para este ejemplo, elegí usar creat()
en lugar de open()
porque hay menos parámetros. Las macros C para las banderas no se pueden usar desde GDB (no usa encabezados C), por lo que tendría que leer los archivos de encabezado para descubrir esto; no es tan difícil hacerlo, pero tomaría más tiempo. Tenga en cuenta que 0600 es el permiso octal para el propietario que tiene acceso de lectura/escritura y el grupo y otros que no tienen acceso. También funcionaría usar 0 para ese parámetro y ejecutar chmod en el archivo más adelante.
Después de eso verifico el resultado:
ls -l /proc/6760/fd/
total 3
lrwx—— 1 rjc rjc 64 2008-02-27 15:32 0 -> /dev/pts/5
l-wx—— 1 rjc rjc 64 2008-02-27 15:32 1 -> /tmp/foo3 <====
lrwx—— 1 rjc rjc 64 2008-02-27 15:32 2 -> /dev/pts/5
Escribiendo más datos en cat
da como resultado el archivo /tmp/foo3
siendo anexado a.
Si desea cerrar la sesión original, debe cerrar todos los identificadores de archivos, abrir un nuevo dispositivo que pueda ser el tty de control y luego llamar a setsid()
.
También puedes hacerlo usando reredirect
(https://github.com/jerome-pouiller/reredirect/).
El siguiente comando redirige las salidas (estándar y error) del proceso PID
a FILE
:
reredirect -m FILE PID
El README
de reredirect
también explica otras características interesantes:cómo restaurar el estado original del proceso, cómo redirigir a otro comando o redirigir solo stdout o stderr.
La herramienta también proporciona relink
, un script que permite redirigir las salidas al terminal actual:
relink PID
relink PID | grep usefull_content
(reredirect
parece tener las mismas características que Dupx descrito en otra respuesta, pero no depende de Gdb).