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/myerrpartir 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
gdben otra terminal y ejecute los siguientes comandos gdbdespués de eso, todos los datos que se escriben
stderrse redirigen a/abs/olu/te/path/filename, ya queattach PIDadjunta el proceso a gdb y lo detienecall close(2)cierra elstderrdescriptor de archivo del proceso (parastdoutel 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 PIDcontinú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
openen la tercera línea están documentados enman 2 open. En mi caso, 65 significa queopendeberí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óndexxxestá 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/nullcomo mi,errfileasí que no lo necesitabaO_CREAT. Y alO_WRONLYser 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.