Termina ogni processo in background


10

Ho alcuni Stoppedprocessi in background.

kill $(jobs -p)e kill `jobs -p`non hanno alcun effetto

kill %1, kill %2ecc. terminano con successo singoli processi

Come posso uccidere ogni processo in background con un comando?

Inoltre, perché i primi due comandi non funzionano per me?

Sto eseguendo Linux Mint 15, 64 bit

Risposte:


10

Quando corrono

Sembra che tu possa semplicemente farlo con kille l'output di jobs -p.

Esempio

$ sleep 1000 &
[1] 21952
$ sleep 1000 &
[2] 21956
$ sleep 1000 &
[3] 21960

Ora ho 3 lavori falsi in esecuzione.

$ jobs
[1]   Running                 sleep 1000 &
[2]-  Running                 sleep 1000 &
[3]+  Running                 sleep 1000 &

Uccidili tutti così:

$ kill $(jobs -p)
[1]   Terminated              sleep 1000
[2]-  Terminated              sleep 1000
[3]+  Terminated              sleep 1000

Confermando che sono andati tutti.

$ jobs
$

Quando sono fermati

Se hai dei lavori che sono stati fermati, non eseguirli invece.

Esempio

$ kill $(jobs -p)

$ jobs
[1]+  Stopped                 sleep 1000
[2]-  Stopped                 sleep 1000
[3]   Stopped                 sleep 1000

OK, questo non li ha uccisi, ma è perché il segnale di uccisione non può essere gestito dal processo stesso, è interrotto. Quindi dì al sistema operativo invece di uccidere. Ecco a cosa -9serve.

$ kill -9 $(jobs -p)
[1]+  Killed                  sleep 1000
[2]-  Killed                  sleep 1000
[3]   Killed                  sleep 1000

Va meglio.

$ jobs
$ 

Quando alcuni sono in esecuzione e alcuni vengono arrestati

Se hai una serie mista di processi in cui alcuni sono arrestati e alcuni sono in esecuzione, puoi fare un killprimo seguito da a kill -9.

$ kill $(jobs -p); sleep <time>; \
    kill -18 $(jobs -p); sleep <time>; kill -9 $(jobs -p)

Estendere leggermente il tempo se è necessario altro per consentire ai processi di arrestarsi per primi.

segnali

Né un HUP (-1) o un SIGTERM (-15) da uccidere riusciranno. Ma perché? Questo perché questi segnali sono più gentili, nel senso che stanno dicendo all'applicazione di terminarsi. Tuttavia, poiché l'applicazione si trova in uno stato di arresto, non è in grado di elaborare questi segnali. Quindi il tuo unico corso è usare un SIGKILL (-9).

Puoi vedere tutti i segnali che killfornisce kill -l.

$ kill -l | column -t
1)   SIGHUP       2)   SIGINT       3)   SIGQUIT      4)   SIGILL       5)   SIGTRAP
6)   SIGABRT      7)   SIGBUS       8)   SIGFPE       9)   SIGKILL      10)  SIGUSR1
11)  SIGSEGV      12)  SIGUSR2      13)  SIGPIPE      14)  SIGALRM      15)  SIGTERM
16)  SIGSTKFLT    17)  SIGCHLD      18)  SIGCONT      19)  SIGSTOP      20)  SIGTSTP
21)  SIGTTIN      22)  SIGTTOU      23)  SIGURG       24)  SIGXCPU      25)  SIGXFSZ
26)  SIGVTALRM    27)  SIGPROF      28)  SIGWINCH     29)  SIGIO        30)  SIGPWR
31)  SIGSYS       34)  SIGRTMIN     35)  SIGRTMIN+1   36)  SIGRTMIN+2   37)  SIGRTMIN+3
38)  SIGRTMIN+4   39)  SIGRTMIN+5   40)  SIGRTMIN+6   41)  SIGRTMIN+7   42)  SIGRTMIN+8
43)  SIGRTMIN+9   44)  SIGRTMIN+10  45)  SIGRTMIN+11  46)  SIGRTMIN+12  47)  SIGRTMIN+13
48)  SIGRTMIN+14  49)  SIGRTMIN+15  50)  SIGRTMAX-14  51)  SIGRTMAX-13  52)  SIGRTMAX-12
53)  SIGRTMAX-11  54)  SIGRTMAX-10  55)  SIGRTMAX-9   56)  SIGRTMAX-8   57)  SIGRTMAX-7
58)  SIGRTMAX-6   59)  SIGRTMAX-5   60)  SIGRTMAX-4   61)  SIGRTMAX-3   62)  SIGRTMAX-2
63)  SIGRTMAX-1   64)  SIGRTMAX

Se volete saperne ancora di più sui vari segnali altamente incoraggio uno a dare un'occhiata alla pagina di segnali uomo man 7 signal.


perché abbiamo un +simbolo per il primo processo e un -simbolo per il secondo processo e nessun simbolo nel terzo?
Ramesh,

Ho ottenuto gli stessi risultati come te. Comunque voglio terminateinvece di kill, visto che ho letto che è più sicuro. Ci ho provato kill -15 $(jobs -p), ma questo non ha avuto effetto. Immaginavo che i processi arrestati possano essere solo interrotti, ma di nuovo kill %numberterminano i processi (individuali) arrestati.
user49888

@Ramesh Gli +e -sono solo gli ultimi processi che ho toccato durante l'impostazione degli esempi. Ciò +significa che qualsiasi comando che non include esplicitamente a %#agirà su quel comando. Il trattino ( -) è il penultimo comando che ho toccato.
slm

@ user49888 - kill -9 .. avrebbe dovuto funzionare. quali sono i processi? Sono processi defunti o orfani?
slm

1
@ user49888 - sì, se il processo si trovava nel mezzo di qualcosa, non gli è stata data la possibilità di eseguire alcuna pulizia prima di essere terminato.
slm

2

Puoi provare questo.

for x in `jobs -p`; do kill -9 $x; done

Tuttavia, se si desidera terminare il processo, è possibile emettere il comando come,

for x in `jobs -p`; do kill -15 $x; done

Dalla pagina di comando WikiKill ,

A un processo è possibile inviare un segnale SIGTERM in quattro modi (in questo caso l'ID processo è "1234"):

kill 1234
kill -s TERM 1234
kill -TERM 1234
kill -15 1234

Il processo può essere inviato un segnale SIGKILL in tre modi:

kill -s KILL 1234
kill -KILL 1234
kill -9 1234

Come spiegato in questa risposta, questa è la differenza tra terminare e uccidere .

Il segnale di terminazione, SIGTERM , è un segnale che può essere intercettato in un programma. Spesso i processi che devono essere eseguiti in background catturano questo segnale e iniziano un processo di arresto, con conseguente uscita pulita. Il segnale di interruzione , SIGKILL , non può essere intercettato. Quando questo viene inviato a un processo, si verificherà una brusca interruzione di quel programma.

Ad esempio, quando si spegne o si riavvia il computer, di solito un SIGTERM viene inviato ai processi in esecuzione, consentendo loro di uscire in modo pulito se lo supportano. Quindi, dopo alcuni secondi, un SIGKILL viene inviato ai processi che sono ancora in esecuzione in modo che le risorse in uso vengano rilasciate forzatamente (ad es. File in uso) e la sequenza di spegnimento possa continuare (ad es. Smontare i filesystem).


Questo fa killogni processo in background. Tuttavia, c'è un modo per terminateloro invece, dal momento che credo che sia più sicuro?
user49888

Se vuoi terminare, puoi usare -15il comando kill.
Ramesh,

-15non funzionerà neanche qui. Vedi la mia A.
slm

@Ramesh: gli ultimi 2 paragrafi non sono corretti. Un SIGTERM non viene inviato (non inizialmente). Si tenta innanzitutto di arrestare i processi tramite gli script di arresto / avvio del servizio. Se questo fosse il caso in cui un 9 è stato inviato al processo, con i processi arrestati come nell'esempio del PO, kill -9nel mio esempio non avrebbe funzionato.
slm

1

Ok, giocando con questo vedo che quando uccidi un lavoro che è stato interrotto (dove l'esecuzione è stata messa in pausa ma non terminata), allora non finirà finché non sarà portato in primo piano. I programmi vengono comunemente arrestati premendo Ctrl- Zsul terminale. La maggior parte dei terminali invia SIGSTOPquesto in questo caso, ma ovviamente ci sono anche altri modi per inviarlo come con kill -STOPo kill -19.

È normale che il programma non finisca immediatamente poiché il programma deve essere in esecuzione per elaborare il SIGTERMsegnale predefinito inviato da kill. Inoltre, a volte dopo l' bashinvio SIGTERMa un processo in background, in qualche modo finisce interrotto (anche se SIGTERMè ancora in sospeso).

Il modo più sicuro per terminare tutti i lavori ( senza ricorrere a kill -9) è prima di inviare SIGTERMun normale kill, quindi di inviare SIGCONTa tutti i lavori rimanenti, ad esempio:

kill $(jobs -p)
kill -18 $(jobs -p)

Il SIGCONT( 18è il numero del segnale) porterà in primo piano tutti i lavori interrotti in modo che possano elaborarli SIGTERMcome farebbero normalmente.

Se tutti i programmi non finiscono con questo, allora ci sono alcuni altri segnali che puoi provare che normalmente completano il processo, prima di ricorrere kill -9. Il primo che raccomando è che SIGHUPmolti programmi che normalmente bloccano gli altri segnali di terminazione rispondono SIGHUP. Di solito viene inviato alla chiusura di un terminale di controllo, in particolare viene inviato al termine di una sshsessione con un terminale tty. Molti programmi interattivi, come le shell, non risponderanno ad altri segnali di terminazione, ma lo faranno poiché sarebbe un problema per loro rimanere in esecuzione al termine di una sshsessione (o dopo la chiusura di qualsiasi terminale di controllo). Per provare questo puoi farlo

kill -1 $(jobs -p)
kill -18 $(jobs -p)

Ancora una volta, ovviamente, è necessario assicurarsi che il programma non sia arrestato in modo che possa elaborare il segnale. Altri segnali di terminazione che puoi provare sono SIGINT( kill -2) e SIGQUIT( kill -3). Ma ovviamente i vantaggi di provare l'intera gamma diminuiscono e possono portare a un inevitabile SIGKILL(aka kill -9).


Se lo fai man signalpuoi ottenere il materiale di riferimento per eseguire il backup.
slm

Questa è una forma più morbida di ciò che la mia A suggerisce. Ci sono casi in cui mi sono imbattuto in passato in cui questo non kill -9 ..risolverà ancora completamente le cose, quindi se lo fai da uno script il metodo funzionerà nella maggior parte dei casi. Questo a volte lascerà i processi in sospeso, quindi fallirà più del tempo. È un compromesso che devi decidere. Meglio essere pesanti e uccidere tutto, rischiando dati / pulizia piuttosto che avere una pulizia più morbida, ma dover fare più analisi man mano che le uccisioni diventano progressivamente più dure.
slm

@slm, dovresti evitare kill -9ogni volta che è possibile, in quanto ciò basta staccare la spina senza dare al programma la possibilità di ripulire correttamente. Aggiornerò con alcune alternative.
Graeme,

Come ho detto, il tuo sapore è più morbido di quello che ho suggerito, dipende da ciò che stai cercando di fare e dalla volontà di tollerare dal punto di vista del rischio. Ho usato il tuo metodo e il mio. Sono entrambi IMO corretti. Anche a kill ..; sleep <time>; kill -18 ..; sleep <time>; uccidere -9 ... . Basically working up to the -9`.
slm

@slm, kill -18è sicuramente qualcosa che dovrebbe essere usato poiché è comune aver interrotto i lavori (e in alcuni casi sembra che in bashqualche modo interrompa l'esecuzione dei lavori prima dell'invio SIGTERM). Come aggiunto sopra SIGHUPvale anche la pena provare poiché molti programmi che non rispondono agli altri risponderanno a questo (provalo con una shell). Oltre a ciò, sì, non è così utile come SIGKILLprobabilmente è inevitabile.
Graeme,

0

Ciò interromperà tutti i lavori nella shell corrente uno per uno:

while kill %; do :; done

Spiegazione: si %riferisce all'ultimo lavoro nell'elenco, quindi verrà eseguito il ciclo fino a quando killnon verrà restituito un valore diverso da zero, il che significherebbe che non ci sono più lavori da terminare.

Un altro approccio potrebbe essere il primo invio SIGTERM, quindi i SIGCONTtuoi lavori possono continuare e la prima cosa che faranno è ricevere il tuo SIGTERM.

/bin/kill $(jobs -p) && /bin/kill -CONT $(jobs -p)

(per qualche motivo il built-in killè strano, quindi ho usato quello esterno qui).

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.