L'emplacement du script d'origine n'est pas disponible sauf si vous utilisez un shell qui offre des extensions à la spécification POSIX. Vous pouvez tester cela avec l'extrait de code suivant:
env -i PATH=/usr/bin:/bin sh -c '. ./included.sh' | grep included
où included.sh
contient
echo "$0"
set
En bash, le nom du script source est dans $BASH_SOURCE
. En zsh (en mode de compatibilité zsh, pas en mode de compatibilité sh ou ksh), c'est dans $0
(notez que dans une fonction, $0
c'est le nom de la fonction à la place). Dans pdksh et dash, il n'est pas disponible. Dans ksh93, cette méthode ne révèle pas la solution, mais le chemin complet vers le script inclus est disponible en tant que ${.sh.file}
.
Si nécessiter bash ou ksh93 ou zsh est suffisant, vous pouvez utiliser cet extrait:
if [ -n "$BASH_SOURCE" ]; then
this_script=$BASH_SOURCE
elif [ -n "$ZSH_VERSION" ]; then
setopt function_argzero
this_script=$0
elif eval '[[ -n ${.sh.file} ]]' 2>/dev/null; then
eval 'this_script=${.sh.file}'
else
echo 1>&2 "Unsupported shell. Please use bash, ksh93 or zsh."
exit 2
fi
Vous pouvez essayer de deviner l'emplacement du script en examinant les fichiers ouverts par le shell. Expérimentalement, cela semble fonctionner avec dash et pdksh mais pas avec bash ou ksh93 qui au moins pour un court script ont fermé le fichier de script au moment où ils se mettent à l'exécuter.
open_file=$(lsof -F n -p $$ | sed -n '$s/^n//p')
if [ -n "$open_file" ]; then
# best guess: $open_file is this script
fi
Le script peut ne pas être le fichier avec le descripteur le plus élevé si le script provient d'un script complexe qui a joué avec des redirections. Vous voudrez peut-être parcourir les fichiers ouverts. Ce n'est pas garanti de fonctionner de toute façon. La seule façon fiable de localiser un script source est d'utiliser bash, ksh93 ou zsh.
Si vous pouvez modifier l'interface, au lieu de rechercher votre script, demandez à votre script d'imprimer un extrait de shell à transmettre à eval
l'appelant. C'est ce que font généralement les scripts pour définir les variables d'environnement. Il permet à votre script d'être écrit indépendamment des aléas du shell de l'appelant et de la configuration du shell.
#!/bin/sh
FOO_DIR=$(dirname -- "$0")
cat <<EOF
FOO_DIR='$(printf %s "$FOO_DIR" | sed "s/'/'\\''/g")'
PATH="\$PATH:$FOO_DIR/bin";
export FOO_DIR PATH
EOF
Dans l'appelant: eval "`/path/to/setenv`"