Je crois $(dirname "$BASH_SOURCE")
fera ce que vous voulez, tant que le fichier que vous recherchez n'est pas un lien symbolique.
Si le fichier que vous recherchez peut être un lien symbolique, vous pouvez faire quelque chose comme ceci pour obtenir le vrai répertoire :
PRG="$BASH_SOURCE"
progname=`basename "$BASH_SOURCE"`
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
dir=$(dirname "$PRG")
Voici ce qui pourrait être une solution élégante :
script_path="${BASH_SOURCE[0]}"
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
Cependant, cela ne fonctionnera pas lors de la recherche de liens. Dans ce cas, on pourrait faire
script_path="$(readlink -f "$(readlink "${BASH_SOURCE[0]}")")"
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
À noter :
- des tableaux comme
${array[x]}
ne sont pas compatibles POSIX - mais alors, leBASH_SOURCE
tableau n'est disponible que dans Bash, de toute façon - sur macOS, le BSD natif
readlink
ne prend pas en charge-f
, vous devrez donc peut-être installer GNUreadlink
en utilisant par ex. infuser parbrew install coreutils
et remplacerreadlink
pargreadlink
- selon votre cas d'utilisation, vous pouvez utiliser le
-e
ou-m
commutateurs au lieu de-f
plus éventuellement-n
; voir la page de manuel readlink pour plus de détails
Une approche différente du problème - si vous utilisez "." afin de définir des variables d'environnement, une autre façon standard de le faire est d'avoir vos commandes de définition de variables d'écho de script, par exemple :
# settings.sh
echo export CLASSPATH=${CLASSPATH}:/foo/bar
puis évaluez la sortie :
eval $(/path/to/settings.sh)
C'est ainsi que fonctionnent les paquets comme les modules. De cette manière, il est également facile de prendre en charge les shells dérivés de sh (X=...; export X
) et csh (setenv X ...
)