Extrait Bash pour avoir tué un processus jusqu'à sa mort?

8

J'essaie d'écrire un script bash robuste et j'y crée un processus d'arrière-plan. À la fin du script, je veux le tuer. J'ai son PID.

Je pensais à quelque chose comme ça

while [[ ps ef $PID ]] ; do
  kill $PID
  sleep 0.5
done

Quelqu'un suggère-t-il quelque chose de mieux? Des problèmes possibles avec cette approche?

Rory
la source
Tu ne voulais pas dire ps -ef?
user1686
1
grawity: C'est juste le style BSD vs les options UNIX, mais ef semble mieux correspondre aux options UNIX. J'irais moi
Kyle Brandt
while [[ ps ef $PID ]]est une erreur de syntaxe. Je suppose que vous vouliez dire while ps ef $PID.
Dennis

Réponses:

10

Le problème avec la mort répétée d'un processus est que vous avez une condition de concurrence avec la création d'un nouveau processus. Ce n'est pas particulièrement probable, mais il est possible que le processus se termine et qu'un nouveau processus démarre avec le même PID pendant que vous dormez.

Pourquoi devez-vous tuer à plusieurs reprises le processus? Si c'est parce que le processus va se terminer, mais qu'il peut prendre un certain temps pour quitter après avoir reçu le signal, vous pouvez utiliser wait:

 kill $PID
 wait $PID

Dans un système idéal, vous n'auriez jamais à répéter un killou un problème kill -9 $PID. Si vous le devez, vous voudrez peut-être envisager de réparer tout ce que vous exécutez afin de ne pas avoir à le faire. En attendant, vous n'atteindrez probablement pas la condition de concurrence, et vous pouvez vous en prémunir en (par exemple) en vérifiant l'horodatage de / proc / $ PID / juste avant de tuer le processus. C'est du mauvais piratage, cependant.

Andrew Aylett
la source
1
Cela ne fonctionne pas si le PID n'appartient pas à un processus enfant, c'est-à-dire que ce script essaie de contrôler l'exécution d'un processus qui a commencé ailleurs. Je reçois bash: wait: pid 32137 is not a child of this shellquand j'essaye. :(
Justin Force
9

Pour tous ceux qui recommandent l'étape de kill $PIDà kill -9 $PID, je dois vous rappeler l' utilisation inutile de kill -9 .

Non non Non. N'utilisez pas kill -9.

Cela ne donne pas au processus une chance de proprement:

  1. arrêter les connexions de socket

  2. nettoyer les fichiers temporaires

  3. informer ses enfants qu'il s'en va

  4. réinitialiser ses caractéristiques de terminal

et ainsi de suite et ainsi de suite et ainsi de suite.

En général, envoyez 15, et attendez une seconde ou deux, et si cela ne fonctionne pas, envoyez 2, et si cela ne fonctionne pas, envoyez 1. Si cela ne fonctionne pas, RETIREZ LE BINAIRE parce que le programme se comporte mal!

N'utilisez pas kill -9. Ne sortez pas la moissonneuse-batteuse juste pour ranger le pot de fleurs.

Maintenant, je ne suis pas d'accord avec le "supprimer la partie binaire", mais la progression semble moins dommageable qu'un simple kill -9.

Je suis également d'accord avec le soin des conditions de concurrence sur la création de nouveaux processus avec le même PID mentionné ici .

Adriano Varoli Piazza
la source
0

Faites d'abord votre mise à mort normale, Sleep x nombre de secondes, puis tuez -9 si elle est toujours là. En outre, cela semble être une situation étrange dans laquelle vous êtes entré, pourrait vouloir nous expliquer le problème plus large.

Kyle Brandt
la source
D'accord. S'il ne répond pas et ne se ferme pas après un SIGTERM (le signal envoyé par défaut par kill), il ne répondra probablement pas à un 2ème, 3ème, 4ème, ...., donc votre prochaine action devrait être SIGKILL (kill - 9). Bien sûr, vous devez vous assurer que le X en "sommeil X secondes" est suffisamment long pour permettre au processus d'effectuer une opération normale de nettoyage de votre bureau et de votre départ même si le système est lourdement chargé - cela peut prendre une fraction de une seconde normalement mais des dizaines de secondes lorsque le système se débat.
David Spillett
0

En règle générale, vous voulez d' kill $PIDabord essayer ,

puis laissez-le dormir un peu pour voir s'il se fermera correctement.

Sinon, exécutez-le kill -9 $PIDpour vous en débarrasser avec force.

Brent
la source
-1

pourquoi pas

kill -9 $PID

chris
la source
2
Parce que vous voulez donner aux processus une chance de se nettoyer et de bien mourir, c'est ce que fait le signal TERM (le signal par défaut). Le signal KILL ("-9") ne donne aucune chance aux processus.
ktower
Bon point, mais l'affiche originale disait qu'il voulait juste le tuer.
chris