web-dev-qa-db-fra.com

Comment arrêter une bash en boucle s'exécutant en arrière-plan?

J'ai commencé une boucle while comme suit:

while true; do {command}; sleep 180; done &

Notez le &.

Je pensais que lorsque je tuerais le terminal, cette boucle while s'arrêterait. Mais ça continue. Cela fait des heures que j'ai tué la session finale.

Comment puis-je arrêter cette boucle while?

21
Saqib Ali

J'ai commencé

while true; do yad; sleep 60; done &

et fermé le terminal pour le tester, maintenant j'ai le même problème.

Si vous avez déjà fermé le terminal, vous avez démarré la boucle

Voyons un aperçu des processus en cours d'exécution avec ps fjx, les dernières lignes de ma machine lues.

 2226 11606 11606 19337 ?           -1 S     1000   0:00  \_ /bin/bash
11606 22485 11606 19337 ?           -1 S     1000   0:00  |   \_ sleep 10
 2226  9411  9411  8383 ?           -1 S     1000   0:00  \_ /bin/bash
 9411 17674  9411  8383 ?           -1 Sl    1000   0:00      \_ yad
    1  2215  2215  2215 ?           -1 Ss    1000   0:00 /lib/systemd/systemd --user
 2215  2216  2215  2215 ?           -1 S     1000   0:00  \_ (sd-pam)

Vous pouvez voir yadcomme un sous-processus de /bin/bash, si je ferme yadname__, il devient sleep 60 dans la sortie de psname__. Si l'arborescence est trop déroutante, vous pouvez également rechercher le résultat comme suit1:

ps fjx | grep "[y]ad"  # or respectively
ps fjx | grep "[s]leep 60"

Les lignes de sortie commencent par deux nombres, le premier étant le PPID, l'ID de processus du processus parent et le second étant le PID, l'ID du processus lui-même. C'est à cause de cela que 9411 apparaît dans les deux lignes ici:

2226  9411  9411  8383 ?           -1 S     1000   0:00  \_ /bin/bash
9411 17674  9411  8383 ?           -1 Sl    1000   0:00      \_ yad

C’est le sous-shell bashque nous voulons tuer et nous venons de découvrir son PID, alors tout ce qui reste est simple

kill 9411  # replace 9411 with the PID you found out!

et l'ennuyeux sous-shell est parti pour de bon.

1Remarque: La notation sous la forme grep "[y]ad" au lieu de simplement grep yad empêche le processus grepde s'afficher dans la liste des résultats.


Si le terminal est encore ouvert

bashfournit la variable $!, qui "s'étend à l'ID de processus du travail le plus récemment placé en arrière-plan", de sorte que ce qui suit tue simplement le dernier processus en arrière-plan:

kill $!

Si c'est pas le dernier processus, vous pouvez simplement obtenir une liste des tâches en cours d'exécution avec le nom intégré jobsname__:

[1]-  Running                 while true; do
    yad; sleep 60;
done &
[2]+  Stopped                 sleep 10

Il existe deux tâches dans la liste des tâches. Pour en supprimer une, vous pouvez y accéder avec le numéro de tâche ou les raccourcis %, %+ ("tâche en cours") et %- ("tâche précédente"), par exemple. pour tuer la boucle en arrière-plan que vous pourriez faire

kill %1  # or
kill %-

et pour tuer le travail sleep 10 suspendu:

kill %2  # or
kill %+  # or
kill %
37
dessert

Je dois noter que lorsque vous fermez le terminal où vous avez entré cette commande, la sous-commande aurait dû mourir avec elle. Essayer de reproduire cela a montré ce comportement.

Maintenant, en supposant que vous vous trouviez dans une situation où cela ne s'est pas produit, vous pouvez supprimer le programme exécuté en arrière-plan, provoqué par le & à la fin de la commande, comme suit:

  1. Ouvrez un nouveau shell et exécutez echo $$ pour noter votre PID (ID de processus) actuel, afin de ne pas tuer votre propre session.
  2. Identifiez le PID du programme que vous pensez toujours en cours d'exécution; Pour ce faire, utilisez la commande ps -ef | grep $Shell afin de rechercher les programmes exécutant un shell.
  3. Notez la deuxième colonne en partant de la gauche et notez la valeur numérique qui diffère de votre résultat echo $$ ci-dessus; c'est le PID que vous voulez tuer.
  4. Exécutez la commande kill -SIGTERM <pid>, où <pid> est la valeur numérique que vous avez identifiée à l'étape 3.
  5. Confirmez que le programme ne fonctionne plus en répétant l'étape 2

Vous pouvez également redémarrer votre session ou votre ordinateur, mais ce qui précède vous permettra d'éviter cela.

5
code_dredd