¿Una alternativa equivalente más amable / gentil / sutil a killall (por ejemplo, "endall")?

17

¿Cómo finalizo todos los procesos con el mismo nombre de una manera más suave que lo killallhace? No quiero interrumpir los procesos, pero les dejo tiempo para salir correctamente.


Ver también:

¿Cómo elimino procesos en Ubuntu?

En el monitor del sistema, ¿cuál es la diferencia entre Kill Process y End Process?

¿Por qué killall (a veces) debe aplicarse dos veces?

tl; dr

loco por natty
fuente
1
¿Y tu pregunta es?
Pilot6
@ Pilot6 reformulado: ¿qué es una alternativa "más suave" a killall?
loco por natty
1
¿Qué es "más suave"?
Pilot6
@ Pilot6 "más suave" en el sentido de "Fin"
loco sobre natty

Respuestas:

43

1. `killall` ya es agradable (SIGTERM)

killallpor defecto envía SIGTERM. Este ya es el buen enfoque que deja a las aplicaciones la oportunidad de limpiar después de sí mismas. El "ve a morir ya, ahora mismo!" enfoque es enviar una SIGKILLseñal, que requiere especificar eso como una opción para killall. De la Biblioteca GNU C: Señales de terminación :

Macro: int SIGTERM

[...] Es la forma normal de pedir cortésmente que un programa finalice.


2. El "proceso de finalización" de System Monitor es igualmente agradable (SIGTERM, también)

Tiene un enlace a una pregunta sobre el Monitor del sistema GNOME. Eso también sirve SIGTERMpara su acción de "Fin del proceso" (y me doy cuenta de que estoy contradiciendo la respuesta a esa pregunta). Puede encontrarlo en el código fuente para verificar usted mismo:

data / menus.ui :

<item>
  <attribute name="label" translatable="yes">_End</attribute>
  <attribute name="action">win.send-signal-end</attribute>
  <attribute name="accel">&lt;Primary&gt;e</attribute>
  <attribute name="target" type="i">15</attribute>
</item>

El 15 aquí es el número de señal. La señal 15 es SIGTERM. Y System Monitor ha utilizado SIGTERMmucho antes de que se hiciera y respondiera esa otra pregunta.


Anexo técnico (en respuesta a un comentario)

Mirando a través de la representación de Github git blame, aquí están los cambios que se han realizado en cómo se deletrean las señales en el código fuente de GNOME System Monitor:

383007f2 24 de julio de 2013 Código duplicado reemplazado para enviar señales con parámetros
GAction 0e766b2d 18 de julio de 2013 Menú emergente del proceso de puertos a GAction
97674c79 3 de octubre de 2012 Deshacerse de la estructura
ProcData 38c5296c 3 de julio de 2011 Hacer que la sangría sea uniforme en los archivos de origen.

Ninguno de estos cambió de SIGQUITa SIGTERM, y ese último fue antes de que se hiciera la pregunta vinculada.

hvd
fuente
77
¡+1 por referirse al código fuente! (+2 por contradecir la "sabiduría convencional", por así decirlo;)
chiflado sobre natty
Bueno, antes de afirmar que está contradiciendo la respuesta: ¿verificó que todas las versiones del código fuente usan 15? Es posible que haya cambiado en algún momento, por lo que la respuesta anterior podría ser 100% correcta con respecto a una versión anterior.
Bakuriu
1
@Bakuriu Contradigo esa respuesta de cualquier manera, pero claro, intentaré recordar comprobar eso la próxima vez que pueda.
hvd
@Bakuriu en el árbol git de origen, git grep 'SIGQUIT'no revela nada. Tampoco se encuentra nada relacionado con las señales git grep '>3<'. Concluyo que lo más probable es que gnome-system-monitor nunca haya usado SIGQUIT.
Ruslan
@Ruslan git grepsolo busca en el árbol actual, no en todo el historial. He utilizado git blame(en realidad el equivalente Github) para profundizar un poco más, pero aún nada.
hvd
5

La respuesta de @hvd es básicamente correcta. Para respaldar eso aún más, el initproceso primero se enviará SIGTERMa los procesos cuando esté apagando su computadora, luego, después de un retraso, se enviará SIGKILLsi aún no han salido. Los procesos no pueden manejar / ignorar SIGKILL.

Sin embargo, para dar un poco más de detalle, la respuesta real es que no tiene forma de saber con certeza si el programa lo maneja. SIGTERMes la señal más habitual para pedir cortésmente que un programa se cierre, pero todo el manejo de la señal depende de que el programa haga algo con la señal.

Para decirlo de otra manera, según las otras respuestas, si tuviera un programa escrito por @Jos o por @AlexGreg, presumiblemente estarían manejando SIGQUITpero posiblemente no SIGTERM, y por SIGTERMlo tanto el envío sería menos "suave" que SIGQUIT.

He escrito un código para que puedas jugarlo tú mismo. Guarde lo siguiente como signal-test.c, luego compile con

gcc -o signal-test signal-test.c

Luego puede ejecutarlo ./signal-testy ver qué sucede cuando envía diferentes señales con killall -s <signal>.

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int flag = 0;

void handle_signal(int s)
{
    flag = s;
}

int main(int argc, char *argv[])
{
    signal(SIGTERM, handle_signal);
    signal(SIGQUIT, handle_signal);

    while(flag == 0){
        sleep(1);
    }
    printf("flag is %d\n", flag);
    return flag;
}

Tal como está, el código maneja tanto SIGTERM como SIGQUIT con gracia. Puede intentar comentar las líneas signal(SIG...(utilizando un //al comienzo de la línea) para eliminar el controlador de señal, luego ejecutar y enviar las señales nuevamente. Debería poder ver estas diferentes salidas:

$ ./signal-test
Terminated

$ ./signal-test
Quit (core dumped)

$ ./signal-test
flag is 15

$ ./signal-test
flag is 3

dependiendo de si manejas las señales o no.

También podría intentar ignorar las señales:

signal(SIGTERM, SIG_IGN);

Si haces eso, el envío SIGTERMno hará nada, tendrás que usarlo SIGKILLpara finalizar el proceso.

Más detalles en man 7 signal. Tenga signal()en cuenta que el uso de esta manera se considera no portátil, ¡aunque es mucho más fácil que la alternativa!

Otra nota al pie de página menor: sobre los killallintentos de Solaris de matar todos los procesos. Todos ellos. Si lo ejecutas como root, te sorprenderás :)

Roger Light
fuente
1
Esta es una de las razones que prefiero pkill. La otra razón es que se empareja pgrep, lo que hace que sea más fácil verificar exactamente qué procesos se eliminarán y cuál tiene una semántica que coincida mejor que ps | grep.
Random832
1

"Fin de todo" sería killall -s SIGQUIT [process name]. Si desea una solución elegante, defina alias endall='killall -s SIGQUIT'.

Jos
fuente
13
SIGQUITes como hacer el proceso abort(3): descarga el núcleo y luego mata el proceso. Esto no es de ninguna manera más agradable / gentil / amable de lo SIGTERMque está predeterminado killall.
Ruslan
3
Para un proceso que maneja señales SIGQUIT(o incluso mejor SIGINT) , podría tratarse más 'suavemente' que SIGTERM, pero esto depende de la aplicación. Sin control, ninguno de ellos causa la terminación inmediata.
R .. GitHub DEJA DE AYUDAR AL HIELO
1
Esta es una gran idea, si le gusta limpiar los archivos principales de todo su disco.
Nate Eldredge
2
@Qix: Una cosa que varía según la señal es si crea un archivo central o no en la acción predeterminada (cuando la aplicación no lo maneja). Probablemente sea preferible usar señales que no generen archivos principales.
R .. GitHub DEJA DE AYUDAR AL HIELO
1
Vale la pena señalar que ubuntu establece el límite de tamaño del archivo central en 0 de manera predeterminada, por lo que SIGQUIT en realidad no producirá un archivo central (si no se maneja) a menos que modifique el límite.
Roger Light