Věřím, že $(dirname "$BASH_SOURCE") bude dělat, co chcete, pokud soubor, který získáváte, není symbolický odkaz.
Pokud soubor, který získáváte, může být symbolický odkaz, můžete udělat něco jako následující, abyste získali skutečný adresář:
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")
Zde je to, co by mohlo být elegantním řešením:
script_path="${BASH_SOURCE[0]}"
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
To však nebude fungovat při získávání odkazů. V takovém případě by se to dalo
script_path="$(readlink -f "$(readlink "${BASH_SOURCE[0]}")")"
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
Věci k poznámce:
- pole jako
${array[x]}nejsou kompatibilní s POSIX - ale pakBASH_SOURCEpole je každopádně dostupné pouze v Bash - v systému macOS, nativní BSD
readlinknepodporuje-f, takže možná budete muset nainstalovat GNUreadlinkpomocí např. vařit podlebrew install coreutilsa nahraďtereadlinkpodlegreadlink - v závislosti na vašem případu použití možná budete chtít použít
-enebo-mpřepínače namísto-fplus možná-n; podrobnosti naleznete na manuálové stránce readlink
Jiný pohled na problém - pokud používáte "." Chcete-li nastavit proměnné prostředí, dalším standardním způsobem, jak toho dosáhnout, je mít ve skriptu příkazy pro nastavení proměnné echo, např.:
# settings.sh
echo export CLASSPATH=${CLASSPATH}:/foo/bar
potom vyhodnoťte výstup:
eval $(/path/to/settings.sh)
Tak fungují balíčky jako moduly. Tento způsob také usnadňuje podporu shellů odvozených od sh (X=...; export X ) a csh (setenv X ... )