script - tuberias y filtros en linux
Cómo redirigir el resultado de un proceso ya en ejecución (5)
Dupx
Dupx es una sencilla herramienta * nix para redirigir la salida / entrada / error estándar de un proceso ya en ejecución.
Motivación
A menudo me he encontrado en una situación en la que un proceso que comencé en un sistema remoto a través de SSH toma mucho más tiempo de lo que había anticipado. Necesito romper la conexión SSH, pero si lo hago, el proceso morirá si intenta escribir algo en stdout / error de una tubería rota. Desearía poder suspender el proceso con ^ Z y luego hacer una
bg %1 >/tmp/stdout 2>/tmp/stderr
Lamentablemente, esto no funcionará (en shells que conozco).
Esta pregunta ya tiene una respuesta aquí:
Normalmente comenzaría un comando como
longcommand &;
Sé que puedes redirigirlo haciendo algo como
longcommand > /dev/null;
por ejemplo, para deshacerse de la salida o
longcommand 2>&1 > output.log
para capturar salida
Pero a veces me olvido, y me preguntaba si hay una forma de capturar o redirigir después del hecho.
longcommand
ctrl-z
bg 2>&1 > /dev/null
o algo así para poder continuar usando el terminal sin que aparezcan mensajes en el terminal.
Consulte Redirigir la salida de un proceso en ejecución .
Primero ejecuto el comando
cat > foo1
en una sesión y pruebo que los datos de stdin se copien en el archivo. Luego, en otra sesión, redirijo la salida.Primero encuentra 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 compruebe los manejadores de archivos 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 ejecute 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 comando
p
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 una llamada al sistemaclose()
y paso el identificador 1, luego ejecuto unacreat()
llamada al sistema para abrir un nuevo archivo. El resultado decreat()
fue 1, lo que significa que reemplazó el manejador de archivo anterior. Si quería usar el mismo archivo para stdout y stderr o si quería reemplazar un manejador de archivo con algún otro número, entonces tendría que llamar a la llamada del sistemadup2()
para lograr ese resultado.Para este ejemplo, elegí usar
creat()
lugar deopen()
porque hay menos parámetros. Las macros C para las banderas no son utilizables desde GDB (no usa encabezados C) así 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 para 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
Escribir más datos en
cat
resultados en el archivo/tmp/foo3
se adjunta.Si desea cerrar la sesión original, debe cerrar todos los manejadores de archivos, abrir un nuevo dispositivo que pueda ser la
setsid()
control y luego llamar asetsid()
.
Recopilé información en Internet y preparé el guión que no requiere ninguna herramienta externa: vea mi respuesta aquí . Espero que sea útil.
También puede hacerlo utilizando reredirect ( https://github.com/jerome-pouiller/reredirect/ ).
Tipo
reredirect -m FILE PID
y las salidas (estándar y error) se escribirán en ARCHIVO.
README reredirect también explica cómo restaurar el estado original del proceso, cómo redirigir a otro comando o redirigir solo stdout o stderr.
(Reredirect parece tener las mismas características que Dupx describió en otra respuesta pero, no depende de Gdb).
Pantalla
Si el proceso se está ejecutando en una sesión de pantalla, puede usar el comando de registro de la pantalla para registrar el resultado de esa ventana en un archivo:
Cambie a la ventana del script, Ca H para iniciar sesión.
Ahora usted puede :
$ tail -f screenlog.2 | grep whatever
Desde la página man de la pantalla:
log [on | off]
Inicie / deje de escribir la salida de la ventana actual en un archivo "screenlog.n" en el directorio predeterminado de la ventana, donde n es el número de la ventana actual. Este nombre de archivo se puede cambiar con el comando ''logfile''. Si no se proporciona ningún parámetro, el estado del registro se alterna. El registro de la sesión se agrega al contenido anterior del archivo si ya existe. El contenido actual y el contenido del historial de desplazamiento no se incluyen en el registro de la sesión. El valor predeterminado es ''off''.
Estoy seguro de que tmux tiene algo similar también.