Question

J'ai un script bash qui fait un peu de traitement parallèle dans une boucle. Je ne veux pas le processus parallèle à pic la CPU, donc j'utiliser une commande de sommeil. Voici une version simplifiée.

(while true;do sleep 99999;done)&

J'exécute la ligne ci-dessus à partir d'une bash rapide et obtenir quelque chose comme: [1] 12345

[1] est le numéro de tâche et 12345 est l'ID de processus (pid) de la boucle tandis que. Je fais kill 12345 et obtenir:

[1]+  Terminated              ( while true; do
    sleep 99999;
done )

Il ressemble a pris fin le script entier. Cependant, je fais un ps aux|grep sleep et trouve la commande de sommeil est toujours forte, mais avec son propre pid! Je peux tuer le sleep et tout semble bien. Cependant, si je devais tuer le premier sommeil, la boucle while commence une nouvelle sleep pid. Cela me est une surprise puisque le sommeil est pas parallèle à la boucle while. La boucle est lui-même un seul chemin d'exécution.

J'ai donc deux questions:

  1. Pourquoi la commande sleep obtenir son propre ID de processus?
  2. Comment puis-je tuer facilement la boucle while et le sommeil?
Était-ce utile?

La solution

  1. Le sommeil obtient son propre PID parce qu'il est un processus en cours et à attendre. Essayez which sleep voir où il est.
  2. Vous pouvez utiliser ps -uf pour voir l'arborescence des processus sur votre système. De là, vous pouvez déterminer ce que le PPID (parent PID) de la coque (celui qui exécute la boucle) du sommeil est.

Autres conseils

Avez-vous essayé de faire kill %1, où 1 est le numéro que vous obtenez après le lancement de la commande en arrière-plan?

Je l'ai fait en ce moment après le lancement (while true;do sleep 99999;done)& et correctement terminé il.

"ps" --ppid sélectionne tous les processus avec le pid parent spécifié, par exemple:

$ (while true;do sleep 99999;done)&
[1] 12345

$ ppid=12345 ; kill -9 $ppid $(ps --ppid $ppid -o pid --no-heading)

Vous pouvez tuer le groupe de processus.

Pour le groupe de processus de votre course de processus:

ps --no-headers -o "%r" -p 15864

Tuez ensuite le groupe de processus avec:

kill -- -[PGID]

Vous pouvez le faire en une seule commande. Essayons sur:

$ (while true;do sleep 99999;done)&
[1] 16151

$ kill -- -$(ps --no-headers -o "%r" -p 16151)
[1]+  Terminated              ( while true; do
    sleep 99999;
done )
  1. Parce que "le sommeil" est un processus, pas une accumulation en fonction ou similaire

  2. Vous pouvez faire ce qui suit:

    (while true;do sleep 99999;done)&
    whilepid=$!
    kill -- -$whilepid
    

Le code ci-dessus tue le groupe de processus, parce que le PID est spécifié comme un nombre négatif (par exemple, au lieu de -123 123). De plus, il utilise la $! variable qui stocke le PID du dernier processus exécuté.

Note: Lorsque vous exécutez un processus en arrière-plan en mode interactif (à savoir en utilisant la ligne de commande rapide), il crée un nouveau groupe de processus, qui est ce qui vous arrive. De cette façon, il est relativement facile de « tuer « em all », parce que vous venez de tuer tout le groupe de processus. Cependant, lorsque la même chose est faite dans un script, il ne crée pas de nouveau groupe, parce que tous les nouveaux processus appartiennent au script PID, même si elles sont exécutées en arrière-plan (contrôle de l'emploi est désactivé par défaut). Pour activer le contrôle des emplois dans un script, il vous suffit de mettre ce qui suit au début du script:

#!/bin/bash

set -m

Pour tuer la boucle while et le sleep en utilisant $! vous pouvez également utiliser un gestionnaire de signal trap à l'intérieur du sous-shell.

(trap 'kill ${!}; exit' TERM; while true; do sleep 99999 & wait ${!}; done)&
kill -TERM ${!}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top