Llevo varios días ejecutando un script. Redirigí stdout a $HOME/mylog
, pero no redirigí stderr ya que pensé que no habría nada en él. De repente, miles de líneas comenzaron a salir en stderr, así que suspendí el trabajo. ¿Hay alguna manera de redirigir stderr a $HOME/myerr
partir de ahora, sin necesidad de reiniciar el script?
Tengo acceso a sudo en la caja y es OS X.
¿Quizás algo que usa dtools trapping?
No puedo perder el trabajo que el script ha hecho hasta ahora y reiniciarlo desde cero. ¿Hay alguna forma de "volcar los objetos en memoria" en el disco, congelar el programa, editar las variables (por ejemplo, los descriptores de archivo) y reanudar con el nuevo contexto?
bash
io-redirection
stdout
Robottinosino
fuente
fuente
Respuestas:
Creo que es posible si adjunta el proceso del intérprete relacionado a gdb. Lo probé con este perl one-liner
y funciona pero desafortunadamente no con un script bash similar.
En primer lugar, debe averiguar el PID de ese proceso cuya salida desea capturar. Luego comience
gdb
en otra terminal y ejecute los siguientes comandos gdbdespués de eso, todos los datos que se escriben
stderr
se redirigen a/abs/olu/te/path/filename
, ya queattach PID
adjunta el proceso a gdb y lo detienecall close(2)
cierra elstderr
descriptor de archivo del proceso (parastdout
el descriptor de archivo es 1)call open(...)
abre un nuevo archivo y toma el número entero sin usar más bajo para el descriptor de archivo recién creado ydetach PID
continúa el procesoAl menos en mi máquina. Las dos primeras líneas son compatibles con POSIX, pero no la tercera.
El segundo y el tercer argumento de
open
en la tercera línea están documentados enman 2 open
. En mi caso, 65 significa queopen
debería crear el archivo y abrir el archivo de solo escritura, es decirO_WRONLY | O_CREAT
(definido enfcntl.h
). El tercer argumento le dice a open que cree el archivo con permiso de lectura y escritura para el usuario, es decirS_IWUSR | S_IRUSR
(definido ensys/stat.h
). Entonces, tal vez tenga que encontrar los valores apropiados en su máquina usted mismo.fuente
Esta es una respuesta cruda y espero que alguien más lo haga mejor, pero si no surgen otras ideas, adjunte gdb y fuerce el proceso a realizar algunas llamadas al sistema:
fuente
open()
captura FD 1? ¿O solo tienes que llamardup()
algunas veces?p open("errfile", O_WRONLY)
realmente funciona en tu máquina?p dup2(xxx, 2)
luegop close(xxx)
dóndexxx
está el valor de retorno deopen
. Esto es algo complicado, mejor no use estos comandos en un proceso de larga duración hasta que esté seguro de que no hay otra opción./dev/null
como mi,errfile
así que no lo necesitabaO_CREAT
. Y alO_WRONLY
ser una macro, si se expande o no depende de si gdb detuvo el proceso en una línea donde los símbolos de depuración están disponibles y la macro está definida. Inyectar código en un proceso con gdb es peligroso y nadie debería copiar estos comandos sin entenderlos.