Hacks de terminaison de processus Bash –
Lors du développement de code Bash multithread, de la gestion des processus serveur ou de la création de chiens de garde de processus, l’un des principaux défis est généralement de terminer correctement, efficacement et précisément les processus Bash existants. Cet article vous montrera comment.
Sommaire
Qu’est-ce qu’un Processus Bash?
Un processus Bash est simplement un exécutable en cours d’exécution. Par exemple, lorsque vous démarrez la calculatrice dans votre environnement de bureau, un processus Bash est créé. Une telle bash a deux identificateurs de processus principaux, à savoir le PID et le PPID, la Identificateur de processus, et le Identificateur de processus parent.
En résumé, le PID contient un identifiant unique basé sur un nombre pour une application en cours d’exécution donnée (c’est-à-dire un processus), alors que le PPID pour toute application en cours d’exécution (c.-à-d. processus) stocke le PID parent du processus qui a démarré cette nouvelle application, d’où le terme «Parent».
Vous pouvez également voir immédiatement comment cela forme une structure arborescente, reliant tous les processus jusqu’à la racine / premier processus qui a un PPID de 0.
Pour un article connexe qui fournit des informations supplémentaires et un exemple pratique de PID et PPID, vous pouvez consulter notre article Exportation de variables dans Bash: l’article Pourquoi et comment.
La gestion des processus Bash semble facile à première vue (exécutez simplement ps -ef
sur la ligne de commande de votre terminal pour voir tous les processus en cours d’exécution sur votre système, précédés de leur PID et PPID identifiants.
Même mettre fin à un processus semble facile, mais les mises en garde et les pièges commencent rapidement à apparaître lorsque vous gérez des systèmes de gestion de processus plus complexes.
Terminer un processus Bash
Commençons simplement en démarrant le gnome-calculator
sur la ligne de commande et par la suite mettre fin au processus.
gnome-calculator & ps -ef | grep gnome-calculator kill -9 $RELEVANT_PID
Nous avons commencé gnome-calculator
en arrière-plan (en utilisant &
à la fin de la commande), afin que nous puissions avoir notre invite de terminal de retour immédiatement sans avoir à démarrer une autre session de terminal.
Ensuite, nous avons utilisé ps -ef
en combinaison avec un tuyau (|
) et le grep
commande pour localiser l’ID de processus (PID) de notre calculatrice. Ensuite, nous l’avons terminé avec un signal 9 kill
commander. Remplacer $RELEVANT_PID
dans le code avec le PID signalé par ps
si vous essayez ce code.
Notez que le processus d’arrière-plan est immédiatement terminé par le kill -9
instruction. Cependant, l’invite de commande Bash revient si rapidement qu’elle est de retour avant même que le planificateur de processus ne puisse signaler que le processus en arrière-plan a été arrêté.
Et, il ne le fera que lorsque cette notification est en ligne avec le travail existant, c’est-à-dire qu’elle est plus basée sur pull que sur push. Lorsque nous appuyons sur Entrée, le système vérifie et nous informe que le premier processus d’arrière-plan est maintenant terminé, ou plutôt a été arrêté / tué; [1]+ Killed gnome-calculator
.
De retour à notre kill command
, un signal 9 kill
est l’un des meurtres les plus destructeurs qui soient. Il termine essentiellement le programme sur place sans être gentil à ce sujet. Vous pouvez consulter la section « Numérotation des signaux pour les signaux standard » accessible depuis le man signal.7
commande exécutée à l’invite de commande de votre terminal pour obtenir une liste de tous les signaux disponibles et leurs numéros correspondants.
Pour les besoins de cet article, nous utiliserons signal 9 pour toujours mettre fin immédiatement et efficacement à un processus. Cependant, même lors de l’utilisation d’un signal 9 arrêt / arrêt de processus, parfois un processus peut s’attarder dans un défunt Etat.
Cela ne se produit pas souvent dans le travail général de DevOps, et si c’est le cas, cela signifie généralement qu’il y avait de graves problèmes dans le code du programme (le processus en cours d’exécution) au départ, ou avec le matériel du système ou le système d’exploitation.
Éviter les erreurs et sélectionner uniquement les processus propriétaires
En recommençant avec le processus ci-dessus, existe-t-il un moyen d’automatiser le PID sélection afin que nous n’ayons pas besoin de taper manuellement, et que nous puissions l’utiliser à partir d’un script? Il y a bien sûr;
gnome-calculator & ps -ef | grep 'gnome-calculator' | grep -v 'grep' | awk '{print $2}' ps -ef | grep 'gnome-calculator' | grep -v 'grep' | awk '{print $2}' | xargs kill -9
Ici, nous avons recommencé notre gnome-calculator
en arrière-plan, et à nouveau utilisé ps
et grep
pour trouver notre processus. C’est là que s’arrête la similitude. Dans l’instruction suivante dans l’ensemble de tubes Bash (en passant les informations de la commande précédente à la suivante en utilisant un symbole de tube: |
) nous excluons le grep
processus lui-même (également répertorié comme faisant partie du ps
sortie telle qu’elle s’exécute pendant notre séquence de commandes et est donc auto-captée par le grep
), en utilisant le -v
option pour grep
et en excluant le mot 'grep'
.
Enfin, nous imprimons le PID (ID de processus) de tout processus découvert en utilisant awk
et imprimer le second ($2
) de la sortie uniquement. Nous voyons qu’un seul PID est retourné, ce qui correspond au fait que nous n’avons qu’un seul gnome-calculator
commencé.
Notre commande finale ajoute un xargs
commande avec un kill -9
instruction de mettre fin à nos processus. xargs fonctionne de manière similaire à un tube en lui-même, mais il est mieux à même de gérer diverses informations d’entrée et de les transmettre correctement, permettant ainsi à certains programmes comme kill
(qui ne peut pas comprendre nativement quand PIDy sont envoyés) pour accepter une entrée directe, ou plutôt des options – comme l’ID de processus transmis ici. Notez que xargs est préfixé par un tube lui-même.
Notre inclusion d’un grep -v 'grep'
évite non seulement l’erreur de l’éventuel kill
commande impossible de trouver le PID associé à l’original grep
commande (comme il s’est terminé depuis, après avoir rempli son devoir de grepping pour le 'gnome-calculator'
text), il évite également le risque de mettre fin à une autre commande / processus plus récent qui aurait pu être démarré depuis l’original grep
terminé, avec le même ID de processus! Bien que la possibilité que cela se produise soit faible, c’est possible.
Travailler ces choses dans notre commande semble mieux, mais ce n’est pas encore parfait. Qu’est-ce que c’est un serveur avec 10 utilisateurs et tous les 10 ont démarré une calculatrice? En supposant que nous ayons des privilèges de type sudo, voulons-nous vraiment mettre fin aux processus de calcul des autres utilisateurs? Probablement pas. Ainsi, nous pouvons aller plus loin et définir notre commande comme suit:
gnome-calculator & ps -ef | grep 'gnome-calculator' | grep -v 'grep' | grep "$(whoami)" | awk '{print $2}' ps -ef | grep 'gnome-calculator' | grep -v 'grep' | grep "$(whoami)" | awk '{print $2}' | xargs kill -9
Dans cet exemple, nous avons inséré une petite commande supplémentaire, à savoir grep "$(whoami)"
, qui a exécuté un sous-shell ($(...)
) puis exécute whoami
dans ce sous-shell. La whoami
La commande retournera au terminal les utilisateurs actuellement connectés. Bingo! Nous terminons désormais uniquement nos propres processus.
Parfait? Non, malheureusement, des erreurs sont toujours possibles même avec une ligne de commande aussi détaillée. Par exemple, si la liste de processus contient des caractères régionaux ou impairs, notre grep
peut potentiellement échouer. Peut-être que la version la plus sûre serait quelque chose de similaire à:
gnome-calculator & ps -ef | grep -Ei --binary-files=text "^$(whoami) [0-9 ]+:.*gnome-calculator$" | grep --binary-files=text -v 'grep' | awk '{print $2}' | grep --binary-files=text -o '[0-9]+' | xargs -I{} kill -9 "{}"
Dans cet exemple, nous avons défini notre grep
commande beaucoup plus restrictive avec une expression régulière: start (indiqué par ^
) avec le nom d’utilisateur (en utilisant whoami
dans un sous-shell), suivi d’un espace obligatoire, suivi uniquement des caractères 0-9
et l’espace, au moins un ou plusieurs (comme indiqué par +
), suivi d’un deux-points obligatoire (une partie du temps), suivi de tout caractère jusqu’au nom de notre programme, qui doit remplir jusqu’à la fin de la ligne (comme indiqué par $
). La grep
utilise des expressions régulières étendues (-E
), et est insensible à la casse (-i
option, ou simplement i
lorsqu’il est ajouté à l’existant -E
option)
Nous avons également protégé notre grep pour la possibilité étrange de paramètres régionaux ou de caractères impairs en utilisant --binary-files=text
, et nous avons écrit nos xargs de manière plus sécurisée en indiquant une chaîne de remplacement et en citant la chaîne de remplacement.
Enfin, nous avons inséré un grep -o
avec une expression régulière qui recherche les nombres 0-9
seulement. Ainsi, même si un programme essayait de tromper ce processus en tuant la ligne de commande, il serait plus difficile de le faire.
Comme alternative intéressante à la définition d’une ligne de commande d’analyse, vous pouvez également consulter la killall
commander:
gnome-calculator & killall 'gnome-calculator'
Pour plus d’informations sur cette commande, vous pouvez accéder au manuel en utilisant man killall
. La killall
La commande vous permet également de définir des options telles que --user
pour tuer uniquement les processus que l’utilisateur spécifié possède, etc.
Emballer
La gestion des processus de différentes manières nous permet d’écrire des scripts de surveillance des processus, d’automatiser la gestion des processus, de mieux développer du code bash multi-thread, de mieux gérer les processus et plus encore. Profitez de vos nouvelles compétences Bash!