2008-09-19 8 views
5

Cuando canaliza dos procesos y mata uno en la "salida" de la tubería, el primer proceso utilizado para recibir la señal "Tubo roto", que generalmente también lo termina. P.ej. corriendo¿Tubo roto ya no termina los programas?

$> do_something_intensive | less 

y se sale de menos utilizados para volver inmediatamente a una cáscara de respuesta, en un SuSE8 o anteriores versiones. cuando intento que hoy, do_something_intensive obviamente sigue ejecutándose hasta que lo mate manualmente. Parece que algo ha cambiado (glib? Shell?) Que hace que el programa ignore las "tuberías rotas" ...

¿Alguien de ustedes tiene pistas sobre esto? cómo restaurar el comportamiento anterior? ¿Por qué ha sido cambiado (o por qué siempre existió semántica múltiple)?

editar: pruebas adicionales (utilizando strace) revelan que "SIGPIPE" se genera, pero que el programa no se interrumpe. Un simple

#include <stdio.h> 
int main() 
{ 
    while(1) printf("dumb test\n"); 
    exit(0); 
} 

continuará con una interminable

--- SIGPIPE (Broken pipe) @ 0 (0) --- 
write(1, "dumb test\ndumb test\ndumb test\ndu"..., 1024) = -1 EPIPE (Broken pipe) 

cuando menos se mata. Seguro que pude por programa de un manejador de señales en mi programa y asegurarse de que termina, pero estoy más en busca de alguna variable de entorno o una opción del shell que obligaría a los programas de interrumpir el SIGPIPE

editar nuevamente: parece ser un problema específico de tcsh (bash lo maneja correctamente) y dependiente de la terminal (Eterm 0.9.4)

+0

Sería de gran ayuda saber qué shell que está utilizando, y más específicamente acerca de lo que realmente hace do_something_intensive. Además, ¿a qué te refieres con "obviamente todavía funcionando"? ¿Aparece en una lista de ps, o es que el shell no responde? ¡Siéntete libre de editar tu pregunta con más detalles! – ehdr

+0

aparece en una lista de PS, el sheel no responde hasta que elimino toda la cadena con CTRL + C y el uso de la CPU aumenta en gkrellm. el shell en uso es tcsh, como se menciona ahora en la pregunta más detallada. Gracias por tu comentario. – PypeBros

Respuesta

0

Gracias por sus consejos, la solución es cada vez más cerca ...

De acuerdo con la página de manual de tcsh, "conchas de inicio de sesión no heredan el comportamiento terminan de sus padres. Otras señales tienen los valores que heredó la cáscara de su padre ".

Lo que sugiere que mi terminal es en realidad la raíz del problema ... si se ignora SIGPIPE, el shell también ignorará SIGPIPE ...

edición: que tengo la confirmación definitiva de que el problema sólo surge con Eterm + tcsh y encontró una señal de recelo que falta (SIGPIPE, SIG_DFL) en el código fuente Eterm. Creo que cierra el caso.

+0

Recuerdo desde hace mucho tiempo que salir de un shell csh con trabajos de backgrouynd permitió que los trabajos siguieran funcionando, pero salir de un shell bash (ksh) acabaría con todos los trabajos no creados. – dsm

+0

eterm/Eterm> svn diff Índice: src/command.c ================================== ================================= --- src/command.c (revisión 40503) +++ src/command.c (copia de trabajo) @@ -2304,6 +2304,7 @@ señal (SIGILL, SIG_DFL); señal (SIGSYS, SIG_DFL); señal (SIGALRM, SIG_DFL); + señal (SIGPIPE, SIG_DFL); #ifdef Señal SIGTSTP (SIGTSTP, SIG_IGN); señal (SIGTTIN, SIG_IGN); – PypeBros

8

Bueno, si hay un intento de escribir en una tubería después de que el lector se haya ido, se genera una señal SIGPIPE . La aplicación tiene la capacidad de atrapar esta señal, pero si no lo hace, el proceso se mata.

El SIGPIPE no se generará hasta que el proceso de llamada intente escribir, por lo que si no hay más resultados, no se generará.

2

¿Ha cambiado algo "hacer algo de manera intensiva"?

Como Daniel ha mencionado, SIGPIPE no es una señal mágica de "su pipa se fue", sino más bien una señal de "buen intento, ya no puede leer/escribir esa tubería".

Si tiene el control de "hacer algo de manera intensiva", puede cambiarlo para escribir un resultado de "indicador de progreso" a medida que gira. Esto elevaría el SIGPIPE de manera oportuna.

+0

sobre do_something_intensive: si estoy haciendo "sí | menos" y poner fin a 'menos', "sí" recibe un SIGPIPE y termina. si en su lugar estoy haciendo "objdump -drS ... | less", continúa "objdump" (a pesar de que strace revela SIGPIPE reapeated); también lo hace un bucle tonto haciendo "printf". – PypeBros

Cuestiones relacionadas