Dans le monde * nix, existe-t-il un moyen pour le script shell d'avoir des informations sur le programme qui l'a exécuté?
Exemple:
/path/to/script1 /path/to/script_xyz
dans ce scénario imaginaire, script_xyz
aurait des informations de chemin ( /path/to/script1
)
ou
processus PID
de l'entité qui l'a exécuté.
Remarque: je suis curieux de connaître différentes solutions et approches, je ne m'attends pas à ce que cela soit réellement possible
shell-script
shell
process
debugging
Miloš Đakonović
la source
la source
Réponses:
Il y a souvent une confusion entre le forking de processus et l'exécution.
Lorsque vous le faites à l'invite d'un
bash
shell.Le processus P1 émettant cette
$
invite exécute actuellement dubash
code. Cebash
code crée un nouveau processus P2 qui s'exécute/bin/sh
puis s'exécute/usr/bin/env
, qui s'exécute ensuite/bin/ps
.Alors P2 a à son tour exécuté code
bash
,sh
,env
etps
.ps
(ou toute autre commande comme un script que nous utiliserions à la place ici) n'a aucun moyen de savoir qu'il a été exécuté par laenv
commande.Tout ce qu'il peut faire est de découvrir quel est son identifiant de processus parent, qui dans ce cas serait P1 ou
1
si P1 est mort dans l'intervalle ou sous Linux un autre processus qui a été désigné comme sous- segment à la place de1
.Il peut alors interroger le système pour savoir quelle commande ce processus est en cours d' exécution (comme avec
readlink /proc/<pid>/exe
Linux) ou quels arguments ont été passés à la dernière commande qu'il a exécutée (comme avecps -o args= -p <pid>
).Si vous voulez que votre script sache ce qui l'a invoqué, un moyen fiable serait de le faire dire à l'invocateur. Cela pourrait être fait par exemple via une variable d'environnement. Par exemple,
script1
pourrait s'écrire:Et
script2
:$INVOKER
contiendra ( généralement ) un chemin versscript1
. Dans certains cas, il peut cependant s'agir d'un chemin relatif et le chemin sera relatif au répertoire de travail en cours au moment duscript1
démarrage. Donc, si vousscript1
changez le répertoire de travail actuel avant d'appelerscript2
,script2
vous obtiendrez des informations erronées sur ce qui l'a appelé. Il peut donc être préférable de s'assurer qu'il$INVOKER
contient un chemin absolu (de préférence en gardant le nom de base) comme en écrivantscript1
:Dans les shells POSIX,
$PPID
contiendra le pid du parent du processus qui a exécuté le shell au moment de son initialisation. Après cela, comme vu ci-dessus, le processus parent peut changer si le processus d'ID$PPID
meurt.zsh
dans lezsh/system
module, peut interroger le courant pid parent de l'enveloppe de courant (sous-) avec$sysparams[ppid]
. Dans les shells POSIX, vous pouvez obtenir le ppid actuel du processus qui a exécuté l'interpréteur (en supposant qu'il est toujours en cours d'exécution) avecps -o ppid= -p "$$"
. Avecbash
, vous pouvez obtenir le ppid du (sous-) shell actuel avecps -o ppid= -p "$BASHPID"
.la source
Oui, un programme peut savoir qui est son parent.
Pour illustrer cela, créons deux scripts bash. Le premier rapporte son PID et démarre le second script:
Le deuxième script rapporte son ID de processus, le PID de son parent et la ligne de commande utilisée pour exécuter le parent:
Maintenant, exécutons-le:
Comme vous pouvez le voir, le deuxième script connaît en fait le PID de son parent. En utilisant
ps
, ce PID révèle la ligne de commande utilisée pour appeler le parent.Pour une discussion plus approfondie du PPID, voir la réponse de Stéphane Chazelas .
la source
s1
,s2
et lesPPID
valeurs mais ensuite, sur plusieurs lignes aprèsERROR: Unsupported SysV option.
et plusieurs lignes avec des explications supplémentaires et - valeur vide pourParent command
ps
duprocps-ng
package, version 3.3.12. Comme Jasen l'a suggéré, vous utilisez probablement une version différente qui peut nécessiter une syntaxe différente pour imprimer la ligne de commande du parent. Essayezps -f | grep $PPID
.