El problema es bastante simple: me resulta útil tener la posibilidad deencender (y apagar)la salida de algún programa en ejecución en cada momento que necesito. Para ser más preciso, quiero tener la libertad de redirigir su salida estándar (y error) desde el shell actual a otro, a /dev/null
un archivo o de regreso al shell original.
Busco algo directo (y seguro) que aproveche el hecho de que sépor adelantadoque encenderé y apagaré las salidas. También publico una respuesta.
Debajo de mi primer intento. Supongamos que trabajo en el caparazón número 35.
$ who am I # the command line to ask where am I
myuser pts/35 ... # The answer
Mi intento comienza con un enlace simbólico a esa terminal.
ln -s /dev/pts/35 MyOutput # The command to link
La idea es iniciar el programa con la redirección configurada a ese enlace.
./Execute_program > MyOutput
Funciona, redirige la salida a mi terminal, pero cuando doy el comando para cambiar el enlace,
ln -sf /dev/null MyOutput
el enlace cambia,pero la redirección no cambiacomo esperaba. No cambia durante el proceso en ejecución. Si lanzo un nuevo programa de la misma manera, la redirección sigue la nueva prescripción del enlace.
Si empiezo de nuevo y configuro el enlace a /dev/null
la salida se suprime como se esperaba, pero nuevamente, cuando cambio el enlace, la redirección no cambia.
Si hago un enlace a un enlace obtengo el mismo resultado. El uso de hard link
no cambia la situación.
Desafortunadamenteel shell expande la línea de comando en el momento del lanzamiento.
¿Existe alguna posibilidad de hacer el trabajo de manera similar o tengo que encontrar cómo comunicar al proceso (o a los PPID) que se cambia el enlace?
Notas:
Esta es una pregunta de la serie "¿Cómo redirigir la salida de un proceso en ejecución?", pero no comienza desde el punto"Ops, lancé el programa y olvidé redirigir la salida. Ahora quiero hacerlo", sino por el contrario: "¿Cómo puedo iniciar un programa con el objetivo explícito de redirigir la salida a otra parte en una etapa posterior?".
Tengo la intención de utilizar dicho procedimiento cuando no sea posible (o conveniente) modificar el código fuente del programa.
Ileerque es posible disown
procesar, usar screen
y transferir de una pantalla a otra... o usar un depurador, interceptar el proceso... Todas esas soluciones podrían funcionar con una buena cantidad de experiencia y esfuerzo, pero algunas de ellas presentan un porcentaje de riesgo también.
Respuesta1
Encuentro una solución a través de mkfifo
, que crea una tubería con nombre, oFIFO.
Sencillo como crear un enlace simbólico y es posible utilizar todas las redirecciones permitidas desde el shell.
mkfifo MyOutput
ls -l
da
0 prw-r--r-- 1 My_username My_username 0 May 11 17:45 MyOut|
Puedo iniciar el programa con redirección a ese enlace.
./Execute_program > MyOutput & cat MyOutput
y la salida comienza a fluir en el terminal.
Si presiono ctrl+ cinterrumpo el flujo pero no el proceso en ejecución (tengo que usar algo como kill pid
o kill %1
para hacerlo).
Cuando por segunda vez le preguntaré alFIFOpara volcar en la terminal (nuevamente con cat MyOutput
) comenzará a volcar la salida a partir de ese momento.
Notas y advertencias:
- Hasta que no le pida un volcado,
FIFOs
contendrá toda la salida.
Como preguntaré la primera vez, seráEnjuagartodo. - Puedo redirigir (o agregar) a otro archivo
cat MyOutput >> NewRealFile
- ¡Puedo usarlo
cat MyOutput
desde otro terminal también! - Advertencia: Si le pido a 2 programas (o instancias) diferentes que redirijan la salida al mismo,
FIFOs
el flujo se fusionará (noa prioriforma de distinguir de qué programas proviene esa línea). - Advertencia: Si pregunto 2 o más veces (tal vez desde diferentes terminales), le dará una línea para cada solicitud, dividiendo la salida para el solicitante. Tal vez haya una solución segura...
Respuesta2
Si entiendo tu pregunta correctamente:
script 1>>~/out.fifo 2>>~/error.fifo
luego para monitorear puedes hacer algo como:
watch cat ~/out.fifo
Podrías usar archivos reales en lugar de Fifos.
script 1>/tmp/$0-out 2>/tmp/$0-error
luego tail -f ellos, serán reemplazados cuando ejecute los scripts nuevamente.
Prefiero el segundo método, o simplemente usar un multiplexor (es decir, pantalla o cualquiera que sea la reencarnación popular de esta semana)
screen -t "name" bash -c 'script'
entonces
screen -r
para "monitorear" y ctrl+ad para desconectar.
Asegúrese de hacer una pausa al final de su script si desea ver el resultado después de ejecutarlo.
Respuesta3
Si yo fuera usted, simplemente redirigiría la salida a un archivo, luego seguiría ese archivo cuando quisiera ver la salida... también es posible que desee limitar el tamaño de ese archivo si cree que la salida va a ser bastante larga, o escriba el archivo en la RAM en lugar de en el disco si cree que la salida será bastante rápida, pero cómo hacer esas cosas es otra cuestión, no lo sé.