Der Speicherort des Skripts ist nur verfügbar, wenn Sie eine Shell verwenden, die Erweiterungen der POSIX-Spezifikation bietet. Sie können dies mit dem folgenden Snippet testen:
env -i PATH=/usr/bin:/bin sh -c '. ./included.sh' | grep included
wo included.sh
enthält
echo "$0"
set
In bash ist der Name des Skripts in $BASH_SOURCE
. In zsh (im zsh-Kompatibilitätsmodus, nicht im sh- oder ksh-Kompatibilitätsmodus) ist es in $0
(beachten Sie, dass in einer Funktion $0
stattdessen der Funktionsname angegeben ist). In pdksh und dash ist es nicht verfügbar. In ksh93 zeigt diese Methode die Lösung nicht an, aber der vollständige Pfad zum enthaltenen Skript ist verfügbar als ${.sh.file}
.
Wenn es gut genug ist, bash oder ksh93 oder zsh zu benötigen, können Sie dieses Snippet verwenden:
if [ -n "$BASH_SOURCE" ]; then
this_script=$BASH_SOURCE
elif [ -n "$ZSH_VERSION" ]; then
setopt function_argzero
this_script=$0
elif eval '[[ -n ${.sh.file} ]]' 2>/dev/null; then
eval 'this_script=${.sh.file}'
else
echo 1>&2 "Unsupported shell. Please use bash, ksh93 or zsh."
exit 2
fi
Sie können versuchen, den Speicherort des Skripts zu erraten, indem Sie sich ansehen, welche Dateien die Shell geöffnet hat. Experimentell scheint dies mit dash und pdksh zu funktionieren, aber nicht mit bash oder ksh93, die zumindest für ein kurzes Skript die Skriptdatei geschlossen haben, bis sie zur Ausführung kommen.
open_file=$(lsof -F n -p $$ | sed -n '$s/^n//p')
if [ -n "$open_file" ]; then
# best guess: $open_file is this script
fi
Das Skript ist möglicherweise nicht die Datei mit dem Deskriptor mit der höchsten Nummer, wenn das Skript in einem komplexen Skript enthalten ist, das mit Umleitungen gespielt hat. Möglicherweise möchten Sie die geöffneten Dateien durchlaufen. Dies funktioniert ohnehin nicht garantiert. Die einzige zuverlässige Möglichkeit, ein Sourcing-Skript zu finden, ist die Verwendung von bash, ksh93 oder zsh.
Wenn Sie die Benutzeroberfläche ändern können, lassen Sie Ihr Skript anstelle der Beschaffung Ihres Skripts ein Shell-Snippet ausdrucken, an das es eval
im Aufrufer übergeben werden soll. Dies ist, was Skripte zum Festlegen von Umgebungsvariablen normalerweise tun. Damit kann Ihr Skript unabhängig von den Abweichungen der Shell und der Shell-Konfiguration des Aufrufers geschrieben werden.
#!/bin/sh
FOO_DIR=$(dirname -- "$0")
cat <<EOF
FOO_DIR='$(printf %s "$FOO_DIR" | sed "s/'/'\\''/g")'
PATH="\$PATH:$FOO_DIR/bin";
export FOO_DIR PATH
EOF
Im Anrufer: eval "`/path/to/setenv`"