Agence web » Actualités du digital » Hacks de terminaison de processus Bash –

Hacks de terminaison de processus Bash –

une-breve-histoire-d39unix-cloudsavvy-it-7337062

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.

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.

Processus racine sous Linux

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

Un processus simple kill sous Linux

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

Terminaison de processus plus bien définie sous Linux

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

Exclusion de processus appartenant à une commande d'arrêt de processus

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 "{}"

Une version plus sûre ou une commande d'arrêt multi-processus

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'

Exemple d'une exécution de commande killall

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!

★★★★★