web-dev-qa-db-fra.com

Obtenir le nom du script de l'appelant dans le script bash

Supposons que j'ai 3 scripts Shell:

script_1.sh

#!/bin/bash
./script_3.sh

script_2.sh

#!/bin/bash
./script_3.sh

le problème est que, dans script_3.sh, je souhaite connaître le nom du script de l'appelant.

pour pouvoir répondre différemment à chaque appelant que je supporte

s'il vous plaît ne supposez pas que je pose des questions sur $0 car $0 fera écho à script_3 à chaque fois, peu importe qui est l'appelant

voici un exemple d'entrée avec la sortie attendue

  • ./script_1.sh devrait faire écho script_1

  • ./script_2.sh devrait faire écho script_2

  • ./script_3.sh devrait echo user_name or root or anything to distinguish between the 3 cases?

Est-ce possible? et si possible, comment peut-on le faire?

ceci va être ajouté à un script rm modifié ... donc quand j'appelle rm il fait quelque chose et quand git ou tout autre outil CLI utilise rm il n'est pas affecté par la modification

27
a14m

D'après la réponse de @ user3100381, voici une commande beaucoup plus simple pour obtenir la même chose qui, à mon avis, devrait être assez portable:

PARENT_COMMAND=$(ps -o comm= $PPID)

Remplacez comm= par args= pour obtenir la ligne de commande complète (commande + arguments). Le = seul est utilisé pour supprimer les en-têtes.

Voir: http://pubs.opengroup.org/onlinepubs/009604499/utilities/ps.html

44

La variable $ PPID contient l'ID de processus parent. Vous pouvez donc analyser la sortie de ps pour obtenir la commande.

#!/bin/bash
PARENT_COMMAND=$(ps $PPID | tail -n 1 | awk "{print \$5}")
13
user3100381

Si vous utilisez sourceing au lieu d'appeler/d'exécuter le script, aucun nouveau processus n'est créé et, par conséquent, les solutions avec ps ne fonctionneront pas de manière fiable.

Utilisez bash caller intégré dans ce cas.

La source

11
Kashyap

Si vous avez /proc:

$(cat /proc/$PPID/comm)
1
J.L.

Quelques fichiers utiles conservés dans/proc/$ PPID ici

  • /proc/*some_process_id*/exe Un lien symbolique vers la dernière commande exécutée sous * nom_processus *
  • /proc/*some_process_id*/cmdline Un fichier contenant la dernière commande exécutée sous * une_id_processus * et des arguments séparés par un octet nul

Donc, une légère simplification. 

sed 's/\x0/ /g' "/proc/$PPID/cmdline"
1
BroSlow

Basé sur @ J.L.answer, avec des explications plus détaillées (la seule commande qui fonctionne pour moi ( linux )):

cat /proc/$PPID/comm

vous donne le nom de la commande du parent pid

Si vous préférez la commande avec toutes les options, alors:

cat /proc/$PPID/cmdline

explications:

  • $PPID est défini par le shell, c’est le pid des processus parents
  • dans /proc/, vous avez quelques répertoires avec le pid de chaque processus ( linux ). Ensuite, si vous cat /proc/$PPID/comm, vous indiquez le nom de commande du PID

Chèque homme proc

1
Gilles Quenot

Vous pouvez simplement utiliser la commande ci-dessous pour éviter d'appeler cut/awk/sed:

ps --no-headers -o command $PPID

Si vous souhaitez uniquement le processus parent et aucun des processus ultérieurs, vous pouvez utiliser:

ps --no-headers -o command $PPID | cut -d' ' -f1
0
Six