Vous pouvez utiliser sh -c
et exec
pour obtenir le PID de la commande avant même son exécution.
Pour commencer myCommand
, afin que son PID soit imprimé avant son exécution, vous pouvez utiliser:
sh -c 'echo $$; exec myCommand'
Comment ça fonctionne:
Cela démarre un nouveau shell, affiche le PID de ce shell, puis utilise la commande exec
intégrée pour remplacer le shell par votre commande, en veillant à ce qu'il ait le même PID. Lorsque votre shell exécute une commande avec la exec
commande intégrée, votre shell est en fait de plus cette commande , plutôt que le comportement plus fréquent de bifurquer une nouvelle copie de lui - même, qui a son propre PID séparé et qui devient alors la commande.
Je trouve cela beaucoup plus simple que des alternatives impliquant une exécution asynchrone (avec &
), un contrôle des travaux ou une recherche avec ps
. Ces approches sont acceptables, mais à moins que vous n'ayez une raison spécifique de les utiliser - par exemple, la commande est peut-être déjà en cours d'exécution. Dans ce cas, il serait logique de rechercher son PID ou d'utiliser le contrôle des tâches - je suggère de commencer par cette méthode. (Et je n’envisagerais certainement pas d’écrire un script complexe ou un autre programme pour y parvenir).
Cette réponse comprend un exemple de cette technique.
Des parties de cette commande peuvent parfois être omises, mais pas habituellement.
Même si le shell que vous utilisez est de type Bourne et prend donc en charge les fonctions exec
intégrées avec ces sémantiques, vous ne devriez généralement pas éviter d'utiliser sh -c
(ou l'équivalent) pour créer un nouveau processus de shell distinct à cette fin, car:
- Une fois que le shell est devenu
myCommand
, il n'y a plus de shell en attente pour exécuter les commandes suivantes. sh -c 'echo $$; exec myCommand; foo
ne serait pas en mesure d'essayer de courir foo
après s'être remplacé avec myCommand
. Sauf si vous écrivez un script qui l'exécute en tant que dernière commande, vous ne pouvez pas l'utiliser uniquement 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 beau que sh -c 'echo $$; exec myCommand'
, mais quand vous courez $$
dedans (
)
, ça 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, que vous pouvez utiliser pour cela. En particulier, dans Bash 4 , (echo $BASHPID; exec myCommand)
fonctionne.
Enfin, notez que certains shells effectuent une optimisation en exécutant une commande comme si exec
(c’est-à-dire qu’ils renonçaient au premier abord) 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 à être exécutée, 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'
vous obtiendrez parfois le bon PID sur certains systèmes avec certains shells. Je recommande de ne jamais compter sur un tel comportement , mais de toujours inclure exec
quand c'est ce dont vous avez besoin.