Mettre fin à chaque processus d'arrière-plan

10

J'ai quelques Stoppedprocessus d'arrière-plan.

kill $(jobs -p)et kill `jobs -p`n'ont aucun effet

kill %1, kill %2Etc. se terminent avec succès les processus individuels

Comment puis-je tuer tous les processus d'arrière-plan avec une seule commande?

Aussi, pourquoi les deux premières commandes ne fonctionnent-elles pas pour moi?

J'utilise Linux Mint 15, 64 bits

user49888
la source

Réponses:

10

Quand ils courent

On dirait que vous pouvez le faire avec killet la sortie de jobs -p.

Exemple

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

Maintenant, j'ai 3 faux emplois en cours.

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

Tuez-les tous comme ça:

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

Confirmant qu'ils sont tous partis.

$ jobs
$

Quand ils sont arrêtés

Si vous avez des travaux arrêtés, ne les exécutez pas, faites-le à la place.

Exemple

$ kill $(jobs -p)

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

D'accord, cela ne les a pas tués, mais c'est parce que le signal de mise à mort ne peut pas être géré par le processus lui-même, il est arrêté. Dites donc à l'OS de tuer à la place. C'est pour ça -9.

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

C'est mieux.

$ jobs
$ 

Quand certains tournent et certains s'arrêtent

Si vous avez un ensemble mixte de processus où certains sont arrêtés et certains sont en cours d'exécution, vous pouvez faire une killpremière suivie d'un kill -9.

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

Prolongez légèrement le temps si vous avez besoin de plus pour permettre aux processus de s'arrêter en premier.

Signaux

Ni un HUP (-1) ni un SIGTERM (-15) à tuer ne réussiront. Mais pourquoi? En effet, ces signaux sont plus doux dans le sens où ils indiquent à l'application de se terminer. Mais puisque l'application est dans un état arrêté, elle ne peut pas traiter ces signaux. Donc, votre seule chose est d'utiliser un SIGKILL (-9).

Vous pouvez voir tous les signaux killfournis avec 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

Si vous voulez en apprendre davantage sur les différents signaux , je vous encourage fortement l' un à jeter un oeil à la page de manuel des signaux, man 7 signal.

slm
la source
pourquoi avons-nous un +symbole pour le premier processus et un -symbole pour le deuxième processus et aucun symbole dans le troisième?
Ramesh
J'ai les mêmes résultats que toi. Cependant, je veux au terminatelieu de kill, car j'ai lu que c'est plus sûr. J'ai essayé kill -15 $(jobs -p), mais cela n'a eu aucun effet. J'ai deviné que les processus arrêtés ne peuvent être tués, mais encore une fois kill %numbermet fin aux processus arrêtés (individuels).
user49888
@Ramesh The +et ne -sont que les derniers processus que j'ai touchés lors de la configuration des exemples. Les +moyens que toutes les commandes qui ne comprennent pas explicitement %#vont agir sur cette commande. Le tiret ( -) est l'avant-dernière commande que j'ai touchée.
slm
@ user49888 - le kill -9 .. devrait avoir fonctionné. quels sont les processus? S'agit-il de processus disparus ou orphelins?
slm
1
@ user49888 - oui si le processus était au milieu de quelque chose, il n'a pas la possibilité de faire un nettoyage avant d'être arrêté.
slm
2

Vous pouvez essayer ça.

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

Cependant, si vous souhaitez mettre fin au processus, vous pouvez exécuter la commande en tant que,

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

Depuis la page de commande WikiKill ,

Un processus peut recevoir un signal SIGTERM de quatre manières (l'ID de processus est «1234» dans ce cas):

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

Le processus peut recevoir un signal SIGKILL de trois manières:

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

Comme expliqué dans cette réponse, c'est la différence entre terminer et tuer .

Le signal de fin, SIGTERM , est un signal qui peut être intercepté dans un programme. Souvent, les processus qui sont censés s'exécuter en arrière-plan captent ce signal et démarrent un processus d'arrêt, ce qui entraîne une sortie propre. Le signal de mise à mort, SIGKILL , ne peut pas être intercepté. Lorsque cela est envoyé à un processus, cela entraînera une interruption brutale de ce programme.

Lorsque vous arrêtez ou redémarrez votre ordinateur par exemple, un SIGTERM est généralement envoyé aux processus en cours d'exécution, ce qui leur permet de quitter de manière propre s'ils le prennent en charge. Ensuite, après quelques secondes, un SIGKILL est envoyé aux processus qui sont toujours en cours d'exécution afin que les ressources utilisées soient libérées de force (par exemple, les fichiers en cours d'utilisation) et que la séquence d'arrêt puisse continuer (par exemple, démonter les systèmes de fichiers).

Ramesh
la source
Cela fait killtous les processus d'arrière-plan. Cependant, y a-t-il un moyen pour terminateeux à la place, car je pense que c'est plus sûr?
user49888
Si vous souhaitez terminer, vous pouvez utiliser -15la commande kill.
Ramesh
-15ne fonctionnera pas ici non plus. Voir mon A.
slm
@Ramesh - les 2 derniers paragraphes ne sont pas corrects. Un SIGTERM n'est pas envoyé (pas initialement). Les processus sont tentés de s'arrêter en premier via leurs scripts d'arrêt / démarrage de service. Si c'était le cas qu'un 9 a été envoyé au processus, alors avec les processus arrêtés comme dans l'exemple du PO, kill -9dans mon exemple, cela n'aurait pas fonctionné.
slm
1

Ok, en jouant avec cela, je vois que lorsque vous tuez un travail qui est arrêté (où l'exécution a été interrompue mais non terminée), il ne se terminera pas tant qu'il ne sera pas mis au premier plan. Les programmes sont généralement arrêtés en appuyant sur Ctrl- Zsur le terminal. La plupart des terminaux envoient le SIGSTOPdans ce cas, mais bien sûr, il existe également d'autres façons de l'envoyer, comme avec kill -STOPou kill -19.

Il est normal que le programme ne se termine pas immédiatement car le programme doit être en cours d'exécution pour traiter le SIGTERMsignal par défaut envoyé par kill. De plus, parfois après l' bashenvoi SIGTERMà un processus d'arrière-plan, il finit en quelque sorte par s'arrêter (bien que le SIGTERMsoit toujours en attente).

Le moyen le plus sûr de terminer tous les travaux ( sans recourir à kill -9) est d'abord d'envoyer SIGTERMavec un travail normal kill, puis d'envoyer SIGCONTles travaux restants, par exemple:

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

Le SIGCONT( 18est le numéro du signal) mettra au premier plan tous les travaux arrêtés afin qu'ils puissent les traiter SIGTERMcomme ils le feraient normalement.

Si tous les programmes ne finissent pas avec cela, il y a quelques autres signaux que vous pouvez essayer qui font normalement terminer le processus, avant de recourir à kill -9. Le premier que je recommande est SIGHUPque de nombreux programmes qui bloquent généralement les autres signaux de terminaison répondent SIGHUP. Ceci est généralement envoyé à la fermeture d'un terminal de contrôle, en particulier il est envoyé à la fin d'une sshsession avec un tty. De nombreux programmes interactifs, tels que les shells, ne répondent pas aux autres signaux de terminaison, mais le feront car il serait difficile pour eux de continuer à fonctionner après la fin d'une sshsession (ou après la fermeture d'un terminal de contrôle). Pour l'essayer, vous pouvez

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

Encore une fois, bien sûr, vous devez vous assurer que le programme n'est pas arrêté afin qu'il puisse traiter le signal. Les autres signaux de terminaison que vous pouvez essayer sont SIGINT( kill -2) et SIGQUIT( kill -3). Mais bien sûr, les avantages d'essayer la gamme complète diminuent et peuvent conduire à une inévitable SIGKILL(aka kill -9).

Graeme
la source
Si vous le faites, man signalvous pouvez obtenir le matériel de référence pour étayer cela.
slm
C'est une forme plus douce de ce que mon A suggère. Il y a des cas où j'ai rencontré par le passé où cela ne nettoiera toujours pas complètement les choses, donc si vous le faites à partir d'un script, la kill -9 ..méthode fonctionnera dans la plupart des cas. Cela laissera parfois traîner les processus et échouera donc la plupart du temps. C'est un compromis que vous devez décider. Mieux vaut être lourd et tuer tout, risquant de perdre des données / nettoyer plutôt que d'avoir un nettoyage plus doux, mais avoir à faire plus d'analyses car vos attaques deviennent progressivement plus dures.
slm
@slm, vous devez éviter kill -9autant que possible car cela débranche simplement la prise sans donner au programme une chance de nettoyer correctement. Je mettrai à jour avec quelques alternatives.
Graeme
Comme je l'ai dit, votre saveur est plus douce que ce que j'ai suggéré, cela se résume à ce que vous essayez de faire par rapport à votre volonté de tolérer du point de vue du risque. J'ai utilisé ta méthode aussi bien que la mienne. Ils sont tous les deux corrects à l'OMI. Aussi un kill ..; sleep <time>; kill -18 ..; dormir <heure>; tuer -9 ... . Basically working up to the -9`.
slm
@slm, kill -18c'est certainement quelque chose qui devrait être utilisé car il est courant d'avoir arrêté des travaux (et dans certains cas, il semble que, d'une bashmanière ou d'une autre, il s'arrête d'exécuter des travaux avant d'envoyer SIGTERM). Comme ajouté ci SIGHUP- dessus vaut également la peine d'être essayé car de nombreux programmes qui ne répondent pas aux autres y répondront (essayez-le avec un shell). Au-delà de cela, oui, cela ne vaut pas la peine, car SIGKILLc'est probablement inévitable.
Graeme
0

Cela mettra fin à tous les travaux dans votre shell actuel un par un:

while kill %; do :; done

Explication: %fait référence au dernier travail de la liste, donc il bouclera jusqu'à ce qu'il killretourne une valeur non nulle, ce qui signifierait qu'il n'y a plus de travaux à terminer.

Une autre approche pourrait être d'envoyer d'abord SIGTERM, SIGCONTpour que vos tâches puissent continuer et la première chose à faire est de recevoir votre SIGTERM.

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

(pour une raison quelconque, intégré killest bizarre, j'ai donc utilisé un externe ici).

dnt
la source