Question Comment puis-je connaître le nom du fichier de script dans un script Bash?


Comment puis-je déterminer le nom du fichier de script Bash dans le script lui-même?

Comme si mon script est dans le fichier runme.sh, comment puis-je le faire pour afficher le message "Vous exécutez runme.sh" sans le coder en dur?


434
2017-10-10 17:20


origine


Réponses:


me=`basename "$0"`

Pour lire un lien symbolique, qui n'est généralement pas ce que vous voulez (vous ne voulez généralement pas confondre l'utilisateur de cette façon), essayez:

me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")"

OMI, cela produira des résultats confus. "J'ai couru foo.sh, mais il dit que je cours bar.sh!? Doit être un bug!" En outre, l'un des objectifs de la création de liens symboliques différents est de fournir des fonctionnalités différentes en fonction du nom sous lequel il est appelé (pensez à gzip et gunzip sur certaines plates-formes).


458
2017-10-10 17:23



# ------------- SCRIPT ------------- #

#!/bin/bash

echo
echo "# arguments called with ---->  ${@}     "
echo "# \$1 ---------------------->  $1       "
echo "# \$2 ---------------------->  $2       "
echo "# path to me --------------->  ${0}     "
echo "# parent path -------------->  ${0%/*}  "
echo "# my name ------------------>  ${0##*/} "
echo
exit

# ------------- APPELÉ ------------- #

# Remarque sur la ligne suivante, le premier argument est appelé dans le double,
# et guillemets simples, car il contient deux mots

$ /misc/shell_scripts/check_root/show_parms.sh "" bonjour "" "'william'"

# ------------- RÉSULTATS ------------- #

# arguments appelés avec ---> 'bonjour là' 'william'
# $ 1 ----------------------> 'bonjour là'
# $ 2 ----------------------> 'william'
# chemin vers moi --------------> /misc/shell_scripts/check_root/show_parms.sh
# chemin parent -------------> / misc / shell_scripts / check_root
# mon nom -----------------> show_parms.sh

# ------------- FIN ------------- #

202
2017-08-28 00:35



Avec bash> = 3 les travaux suivants:

$ ./s
0 is: ./s
BASH_SOURCE is: ./s
$ . ./s
0 is: bash
BASH_SOURCE is: ./s

$ cat s
#!/bin/bash

printf '$0 is: %s\n$BASH_SOURCE is: %s\n' "$0" "$BASH_SOURCE"

156
2018-03-12 16:48



Si le nom du script comporte des espaces, une méthode plus robuste consiste à utiliser "$0" ou "$(basename "$0")" - ou sur MacOS: "$(basename \"$0\")". Cela évite que le nom soit déchiré ou interprété de quelque manière que ce soit. En général, il est recommandé de toujours citer les noms de variables dans le shell.


57
2017-10-10 17:26



$BASH_SOURCE donne la bonne réponse lors de la recherche du script.

Cela inclut cependant le chemin pour obtenir uniquement le nom du fichier de scripts, utilisez:

$(basename $BASH_SOURCE) 

54
2018-06-15 09:27



Si vous le voulez sans le chemin alors vous utiliseriez ${0##*/}


21
2017-10-10 19:14



Répondre Chris Conway, sur Linux (au moins), vous feriez ceci:

echo $(basename $(readlink -nf $0))

readlink affiche la valeur d'un lien symbolique. S'il ne s'agit pas d'un lien symbolique, il imprime le nom du fichier. -n lui dit de ne pas imprimer une nouvelle ligne. -f lui dit de suivre complètement le lien (si un lien symbolique était un lien vers un autre lien, cela résoudrait aussi celui-ci).


19
2017-10-10 18:21



Ces réponses sont correctes pour les cas qu'ils indiquent mais il y a toujours un problème si vous exécutez le script à partir d'un autre script en utilisant le mot-clé 'source' (pour qu'il s'exécute dans le même shell). Dans ce cas, vous obtenez le $ 0 du script appelant. Et dans ce cas, je ne pense pas qu'il soit possible d'obtenir le nom du script lui-même.

Ceci est un cas de figure et ne doit pas être pris au sérieux. Si vous exécutez directement le script à partir d'un autre script (sans 'source'), l'utilisation de $ 0 fonctionnera.


11
2018-03-12 15:34



J'ai trouvé que cette ligne fonctionnait toujours, que le fichier soit en cours d'exécution ou exécuté en tant que script.

echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"

Si vous voulez suivre les liens symboliques, utilisez readlink sur le chemin que vous obtenez ci-dessus, de manière récursive ou non récursive.

La raison pour laquelle la ligne unique fonctionne s'explique par l'utilisation de la BASH_SOURCE variable d'environnement et son associé FUNCNAME.

BASH_SOURCE

Une variable tableau dont les membres sont les noms de fichiers source où sont définis les noms de fonction shell correspondants dans la variable de tableau FUNCNAME. La fonction shell $ {FUNCNAME [$ i]} est définie dans le fichier $ {BASH_SOURCE [$ i]} et appelée depuis $ {BASH_SOURCE [$ i + 1]}.

FUNCNAME

Une variable tableau contenant les noms de toutes les fonctions shell actuellement dans la pile des appels d'exécution. L'élément avec index 0 est le nom de toute fonction shell en cours d'exécution. L'élément le plus bas (celui avec l'index le plus élevé) est "principal". Cette variable n'existe que lorsqu'une fonction shell est en cours d'exécution. Les affectations à FUNCNAME n'ont aucun effet et renvoient un statut d'erreur. Si FUNCNAME n'est pas défini, il perd ses propriétés spéciales, même s'il est réinitialisé par la suite.

Cette variable peut être utilisée avec BASH_LINENO et BASH_SOURCE. Chaque élément de FUNCNAME possède des éléments correspondants dans BASH_LINENO et BASH_SOURCE pour décrire la pile d'appels. Par exemple, $ {FUNCNAME [$ i]} a été appelé depuis le fichier $ {BASH_SOURCE [$ i + 1]} au numéro de ligne $ {BASH_LINENO [$ i]}. L'appelant intégré affiche la pile d'appels en cours à l'aide de ces informations.

[Source: manuel Bash]


11
2017-08-31 20:59