Ich glaube $(dirname "$BASH_SOURCE")
wird tun, was Sie wollen, solange die Datei, die Sie beschaffen, nicht ist ein Symlink.
Wenn die Datei, die Sie beziehen, möglicherweise ein Symlink ist, können Sie so etwas wie das Folgende tun, um das wahre Verzeichnis zu erhalten:
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")
Hier ist eine elegante Lösung:
script_path="${BASH_SOURCE[0]}"
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
Beim Sourcing von Links funktioniert dies jedoch nicht. In diesem Fall könnte man es tun
script_path="$(readlink -f "$(readlink "${BASH_SOURCE[0]}")")"
script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
Zu beachten:
- Arrays wie
${array[x]}
sind nicht POSIX-kompatibel - aber dann dieBASH_SOURCE
array ist ohnehin nur in Bash verfügbar - unter macOS das native BSD
readlink
unterstützt-f
nicht , daher müssen Sie möglicherweise GNUreadlink
installieren mit z.B. Brauen mitbrew install coreutils
und ersetzen Siereadlink
vongreadlink
- Abhängig von Ihrem Anwendungsfall möchten Sie vielleicht den
-e
verwenden oder-m
Schalter statt-f
plus evtl.-n
; siehe Readlink-Manpage für Details
Eine andere Herangehensweise an das Problem - wenn Sie "." Um Umgebungsvariablen zu setzen, besteht eine andere Standardmethode darin, dass Ihr Skript Befehle zum Setzen von Variablen zurückgibt, z. B.:
# settings.sh
echo export CLASSPATH=${CLASSPATH}:/foo/bar
dann die Ausgabe auswerten:
eval $(/path/to/settings.sh)
So funktionieren Pakete wie Module. Auf diese Weise ist es auch einfach, Shells zu unterstützen, die von sh (X=...; export X
) und csh (setenv X ...
)