Comment arrêter un bash pendant que la boucle s'exécute en arrière-plan?


23

J'ai commencé une boucle while comme suit:

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

Remarquez le &.

J'ai pensé que lorsque j'aurais tué le terminal, cette boucle s'arrêterait. Mais ça continue. Cela fait des heures que j'ai tué la session terminale.

Comment puis-je arrêter cette boucle while?

Réponses:


38

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 commencé la boucle

Voyons un aperçu des processus en cours d'exécution ps fjx, les dernières lignes de ma machine sont 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, yadil se transforme sleep 60en sortie de ps. Si l'arborescence est trop confuse, vous pouvez également rechercher la sortie comme suit 1 :

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 qui 9411apparaî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 bashsous - shell que nous voulons tuer et nous venons de découvrir son PID, alors maintenant tout ce qui reste est simple

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

et le sous-shell ennuyeux a disparu pour de bon.

1 : La notation au grep "[y]ad"lieu d' grep yadempêcher simplement le grepprocessus lui-même de s'afficher dans la liste des résultats.


Si le terminal est toujours 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 ce n'est pas le dernier processus, vous pouvez simplement obtenir une liste des travaux en cours d'exécution avec la jobssortie intégrée, par exemple:

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

Il y a deux jobs dans la liste des jobs, pour en tuer un, vous pouvez y accéder avec le numéro de job ou les raccourcis %, %+("job actuel") et %-("job précédent"), par exemple pour tuer la boucle qui s'exécute en arrière-plan pourrait faire

kill %1  # or
kill %-

et pour tuer le sleep 10travail suspendu :

kill %2  # or
kill %+  # or
kill %

5

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 êtes effectivement dans une situation où cela ne s'est pas produit, une façon de tuer le programme que vous avez laissé en cours d'exécution en arrière-plan, qui a été causée par le &à la fin de la commande, est la suivante:

  1. Ouvrez un nouveau shell et exécutez echo $$pour noter votre PID actuel (ID de processus), afin de ne pas tuer votre propre session.
  2. Identifiez le PID du programme qui, selon vous, est toujours en cours d'exécution; vous pouvez le faire en utilisant la ps -ef | grep $SHELLcommande pour trouver quels programmes exécutent un shell.
  3. Notez la 2e colonne de gauche et notez la valeur numérique qui diffère de votre echo $$résultat ci-dessus; c'est le PID que vous voulez tuer.
  4. Exécutez la kill -SIGTERM <pid>commande, 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.


2
Vous pouvez également utiliser toppour arrêter le processus en appuyant sur k, puis en entrant le PID, puis en appuyant deux fois sur entrée.
luk3yx

-1

Le &fera le terminal créer un nouveau processus et obtenir votre code à exécuter à l' intérieur. Ainsi, votre code devient indépendant du processus terminal. Même si vous fermez le terminal, le nouveau processus dans lequel votre code s'exécute ne s'arrêtera pas. Donc, supprimez &ou faites ps -aux, localisez votre processus et tuez-le kill (process id).


-3

Généralement bg pour le fond fg pour le premier plan. Si vous utilisez & symbol use fg, il affichera le programme en cours d'exécution. Appuyez sur Ctrl + C pour tuer.


3
Utiliser bg/ fgne fonctionnera pas une fois le terminal détaché bash. Serait incapable de rattacher à l'aide de reptyrcar basha des processus enfants ( sleep).
xiota

Il a fermé le terminal parce qu'il tuerait ce processus. La prochaine fois, il utilisera fg pour fermer le programme. Simple
Curieux

@Curious c'est la prochaine fois. Mais OP demande à propos de cette fois.
RonJohn
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.