Alternativa equivalente Kinder / Gentler / Sottile alla Killall (es. "Endall")?


17

Come posso terminare tutti i processi con lo stesso nome in un modo più delicato di quanto killallnon faccia? Non voglio interrompere i processi, ma lasciare loro il tempo di chiudere correttamente.


Guarda anche:

Come uccido i processi in Ubuntu?

Nel monitor di sistema, qual è la differenza tra Kill Process e End Process?

Perché killall (a volte?) Deve essere applicato due volte?

tl; dr


1
E la tua domanda è?
Pilota 6

@ Pilot6 riformulato: qual è un'alternativa "più morbida" al killall?
pazzo per il natty del

1
Cosa è "più morbido"?
Pilota 6

@ Pilot6 "più morbido" nel senso di "End"
nocciola sul natty

Risposte:


43

1. "killall" già carino (SIGTERM)

killallper impostazione predefinita invia SIGTERM. Questo è già il simpatico approccio che lascia alle applicazioni la possibilità di ripulire da sole. Il "vai a morire già, proprio ora!" l'approccio è di inviare un SIGKILLsegnale, che richiede di specificarlo come opzione a killall. Dalla libreria GNU C: segnali di terminazione :

Macro: int SIGTERM

[...] È il modo normale di chiedere educatamente a un programma di terminare.


2. "End process" di System Monitor altrettanto bello (anche SIGTERM)

Si collega a una domanda su GNOME System Monitor. Questo vale anche SIGTERMper la sua azione "Termina processo" (e mi rendo conto di contraddire la risposta a quella domanda). Puoi trovarlo nel codice sorgente per verificare te stesso:

data / menu.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>

Il 15 qui è il numero del segnale. Il segnale 15 è SIGTERM. E System Monitor ha usato SIGTERMmolto prima che l'altra domanda fosse posta e risposta.


Addendum tecnico (in risposta a un commento)

Guardando attraverso la rappresentazione di Github git blame, ecco le modifiche apportate al modo in cui i segnali vengono spiegati nel codice sorgente di GNOME System Monitor:

383007f2, 24 lug 2013 Sostituito il codice duplicato per l'invio di segnali con parametri
GAction 0e766b2d 18 lug 2013 Menu popup del processo di porta su GAtion
97674c79 3 ott 2012 Sbarazzarsi della struttura
ProcData 38c5296c 3 lug 2011 Rendere uniforme il rientro tra i file di origine.

Nessuno di questi è cambiato da SIGQUITa SIGTERM, e l'ultimo è stato prima che fosse posta la domanda collegata.


7
+1 per fare riferimento al codice sorgente! (+2 per contraddire la "saggezza convenzionale", per così dire;)
nocciola circa natty

Bene, prima di affermare che stai contraddicendo la risposta: hai controllato che tutte le versioni del codice sorgente utilizzino 15? Potrebbe essere stato modificato ad un certo punto, quindi la vecchia risposta potrebbe essere corretta al 100% rispetto a una versione precedente.
Bakuriu,

1
@Bakuriu contraddico questa risposta in entrambi i casi, ma punto giusto, cercherò di ricordare di controllare che la prossima volta posso.
hvd,

@Bakuriu nell'albero git di origine, git grep 'SIGQUIT'non rivela nulla. Nulla è correlato ai segnali git grep '>3<'. Concludo che molto probabilmente gnome-system-monitor non ha mai usato SIGQUIT.
Ruslan,

@Ruslan git grepcerca solo l'albero corrente, non l'intera storia. Ho usato git blame(in realtà l'equivalente di Github) per scavare un po 'più a fondo, ma ancora niente.
hvd,

5

La risposta di @hvd è sostanzialmente corretta. Per eseguire il backup ancora di più, il initprocesso invierà prima SIGTERMai processi quando si spegne il computer, quindi dopo un ritardo verrà inviato SIGKILLse non sono già usciti. I processi non possono gestire / ignorare SIGKILL.

Per dare un po 'più di dettagli, la vera risposta è che non hai modo di sapere con certezza che il programma lo gestisce. SIGTERMè il segnale più comune da utilizzare per chiedere educatamente a un programma di uscire, ma tutta la gestione del segnale dipende dal fatto che il programma esegua qualcosa con il segnale.

Per dirla in un modo diverso, basato sulle altre risposte, se avessi un programma scritto da @Jos o da @AlexGreg, presumibilmente avrebbero gestito SIGQUITma forse no SIGTERM, e quindi l'invio SIGTERMsarebbe meno "morbido" di SIGQUIT.

Ho scritto del codice in modo che tu possa giocarci da solo. Salvare il seguito come signal-test.c, quindi compilare con

gcc -o signal-test signal-test.c

È quindi possibile eseguirlo ./signal-teste vedere cosa succede quando si inviano segnali diversi 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;
}

Allo stato attuale, il codice gestisce sia SIGTERM che SIGQUIT con garbo. Potresti provare a commentare le linee signal(SIG...(usando //a all'inizio della linea) per rimuovere il gestore del segnale, quindi eseguire e inviare nuovamente i segnali. Dovresti essere in grado di vedere questi diversi output:

$ ./signal-test
Terminated

$ ./signal-test
Quit (core dumped)

$ ./signal-test
flag is 15

$ ./signal-test
flag is 3

a seconda che tu gestisca o meno i segnali.

Potresti anche provare a ignorare i segnali:

signal(SIGTERM, SIG_IGN);

Se lo fai, l'invio SIGTERMnon farà nulla, dovrai SIGKILLterminare il processo.

Maggiori dettagli in man 7 signal. Si noti che l'utilizzo signal()in questo modo è considerato non portatile, ma è molto più facile dell'alternativa!

Un'altra nota in calce minore: Solaris killalltenta di uccidere tutti i processi. Tutti loro. Se lo esegui come root, potresti essere sorpreso :)


1
Questo è uno dei motivi che preferisco pkill. L'altra ragione è che si accoppia con pgrep, il che rende più facile controllare esattamente quali processi verranno uccisi e quale di per sé ha una semantica di corrispondenza migliore rispetto a ps | grep.
Casuale 832,

1

"Fine tutto" sarebbe killall -s SIGQUIT [process name]. Se vuoi una soluzione elegante, definisci alias endall='killall -s SIGQUIT'.


13
SIGQUITè come fare il processo abort(3): scarica il core e poi uccide il processo. Questo non è in alcun modo più bello / gentile / gentile di quello per SIGTERMcui è predefinito killall.
Ruslan,

3
Per un processo che gestisce i segnali, SIGQUIT(o anche meglio SIGINT) , potrebbe essere trattato più "dolcemente" di SIGTERM, ma dipende dall'applicazione. Non gestiti, ognuno di essi causa la risoluzione immediata.
R .. GitHub smette di aiutare ICE il

1
Questa è un'ottima idea, se ti piace ripulire i file core su tutto il disco.
Nate Eldredge,

2
@Qix: una cosa che varia in base al segnale è se crea un file core o meno sull'azione predefinita (quando non viene gestita dall'applicazione). Probabilmente è preferibile utilizzare segnali che non generano file core.
R .. GitHub smette di aiutare ICE il

1
Vale la pena notare che Ubuntu imposta il limite della dimensione del file core su 0 per impostazione predefinita, quindi SIGQUIT non produrrà effettivamente un file core (se non gestito) a meno che non si modifichi il limite.
Roger Light,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.