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_SOURCE
pole je každopádně dostupné pouze v Bash - v systému macOS, nativní BSD
readlink
nepodporuje-f
, takže možná budete muset nainstalovat GNUreadlink
pomocí např. vařit podlebrew install coreutils
a nahraďtereadlink
podlegreadlink
- v závislosti na vašem případu použití možná budete chtít použít
-e
nebo-m
přepínače namísto-f
plus 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 ...
)