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_SOURCEtableau n'est disponible que dans Bash, de toute façon - sur macOS, le BSD natif
readlinkne prend pas en charge-f, vous devrez donc peut-être installer GNUreadlinken utilisant par ex. infuser parbrew install coreutilset remplacerreadlinkpargreadlink - selon votre cas d'utilisation, vous pouvez utiliser le
-eou-mcommutateurs au lieu de-fplus é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 ... )