GNU/Linux >> Tutoriels Linux >  >> Linux

Comment obtenir le pid du processus qui vient de démarrer

Solution 1 :

Quoi de plus simple que echo $! ? En une seule ligne :

myCommand & echo $!

Solution 2 :

Vous pouvez utiliser sh -c et exec pour obtenir le PID de la commande même avant ça marche.

Pour commencer myCommand , afin que son PID soit imprimé avant qu'il ne commence à s'exécuter, vous pouvez utiliser :

sh -c 'echo $$; exec myCommand'

Comment ça marche :

Cela démarre un nouveau shell, imprime le PID de ce shell, puis utilise le exec intégré pour remplacer le shell avec votre commande, en vous assurant qu'il a le même PID. Lorsque votre shell exécute une commande avec le exec intégré, votre shell est en train de devenir cette commande, plutôt que le comportement plus courant consistant à forker une nouvelle copie d'elle-même, qui a son propre PID séparé et qui devient alors la commande.

Je trouve cela beaucoup plus simple que les alternatives impliquant une exécution asynchrone (avec & ), le contrôle des tâches ou la recherche avec ps . Ces approches sont correctes, mais à moins que vous n'ayez une raison spécifique de les utiliser - par exemple, peut-être que la commande est déjà en cours d'exécution, auquel cas la recherche de son PID ou l'utilisation du contrôle des tâches aurait du sens - je suggère de considérer cette méthode en premier. (Et je n'envisagerais certainement pas d'écrire un script complexe ou un autre programme pour y parvenir).

Cette réponse inclut un exemple de cette technique.

Des parties de cette commande peuvent parfois être omises, mais pas généralement.

Même si le shell que vous utilisez est de style Bourne et prend donc en charge le exec intégré avec cette sémantique, vous ne devriez généralement pas essayer d'éviter d'utiliser sh -c (ou équivalent) pour créer un nouveau, séparé processus shell à cette fin, car :

  • Une fois que le shell est devenu myCommand , aucun shell n'attend pour exécuter les commandes suivantes. sh -c 'echo $$; exec myCommand; foo ne serait pas en mesure d'essayer d'exécuter foo après s'être remplacé par myCommand . À moins que vous n'écriviez un script qui l'exécute comme sa dernière commande, vous ne pouvez pas simplement utiliser echo $$; exec myCommand dans un shell où vous exécutez d'autres commandes.
  • Vous ne pouvez pas utiliser un sous-shell pour cela. (echo $$; exec myCommand) peut être syntaxiquement plus agréable que sh -c 'echo $$; exec myCommand' , mais lorsque vous exécutez $$ à l'intérieur de ( ) , il donne le PID du shell parent, pas du sous-shell lui-même. Mais c'est le PID du sous-shell qui sera le PID de la nouvelle commande. Certains shells fournissent leurs propres mécanismes non portables pour trouver le PID du sous-shell, ce que vous pourriez utiliser pour cela. En particulier, dans Bash 4, (echo $BASHPID; exec myCommand) fonctionne.

Enfin, notez que certains shells effectueront une optimisation où ils exécuteront une commande comme si par exec (c'est-à-dire qu'ils renoncent à bifurquer en premier) quand on sait que le shell n'aura plus rien à faire par la suite. Certains shells essaient de le faire chaque fois que c'est la dernière commande à exécuter, tandis que d'autres ne le feront que lorsqu'il n'y a pas d'autres commandes avant ou après la commande, et d'autres ne le feront pas du tout. L'effet est que si vous oubliez d'écrire exec et utilisez simplement sh -c 'echo $$; myCommand' alors ça va parfois vous donner le bon PID sur certains systèmes avec certains coquilles. Je recommande de ne jamais compter sur un tel comportement, et à la place de toujours inclure exec quand c'est ce dont vous avez besoin.

Solution 3 :

Enveloppez la commande dans un petit script

#!/bin/bash
yourcommand &
echo $! >/path/to/pid.file

Solution 4 :

Je ne connais pas de solution plus simple, mais n'utilise pas $! assez bien? Vous pouvez toujours affecter la valeur à une autre variable si vous en avez besoin plus tard, comme d'autres l'ont dit.

En remarque, au lieu de passer de ps, vous pouvez utiliser pgrep ou pidof .

Solution 5 :

utilisez exec à partir d'un script bash après avoir enregistré le pid dans un fichier :

exemple :

supposons que vous ayez un script nommé "forever.sh" que vous souhaitez exécuter avec les arguments p1,p2,p3

code source pour toujours.sh :

#!/bin/sh

while [ 1 -lt 2 ] ; do
    logger "$0 running with parameters \"[email protected]\""
    sleep 5
done

créez un reaper.sh :

#!/bin/sh

echo $$ > /var/run/$1.pid
exec "[email protected]"

exécutez forever.sh via reaper.sh :

./reaper.sh ./forever.sh p1 p2 p3 p4 &

forever.sh ne fait rien de plus que d'enregistrer une ligne dans syslog toutes les 5 secondes

vous avez maintenant le pid dans /var/run/forever.sh.pid

cat /var/run/forever.sh.pid 
5780

et forever.sh fonctionne correctement. grep syslog :

Nov 24 16:07:17 pinkpony cia: ./forever.sh running with parameters "p1 p2 p3 p4"

vous pouvez le voir dans le tableau des processus :

ps axuwww|grep 'forever.sh p1' |grep -v grep
root      5780  0.0  0.0   4148   624 pts/7    S    16:07   0:00 /bin/sh ./forever.sh p1 p2 p3 p4

Linux
  1. Processus de démarrage Linux :un guide pour démarrer

  2. Comment démarrer avec Juju?

  3. Comment démarrer avec un serveur cloud FreeBSD

  4. Comment trouver l'ID de processus dans Ubuntu ?

  5. Comment obtenir le pid d'un processus et invoquer kill -9 dessus dans le script shell ?

Comment identifier un processus qui n'a pas de PID ?

Lxc et comment commencer ?

Comment trouver le nom du processus à partir de son PID

Comment démarrer avec Arch Linux

Comment démarrer avec Midnight Commander en 2022

Comment faire en sorte que pgrep affiche les informations complètes sur le processus