6176 Stimmen

Wie kann ich das Quellverzeichnis eines Bash-Skripts aus dem Skript selbst abrufen?

Wie erhalte ich den Pfad des Verzeichnisses, in dem ein Bash Skript befindet sich, innerhalb dieses Drehbuch?

Ich möchte ein Bash-Skript als Launcher für eine andere Anwendung verwenden. Ich möchte das Arbeitsverzeichnis in das Verzeichnis ändern, in dem sich das Bash-Skript befindet, damit ich mit den Dateien in diesem Verzeichnis arbeiten kann:

$ ./application

91 Stimmen

Keine der derzeitigen Lösungen funktioniert, wenn es irgendwelche Zeilenumbrüche am Ende des Verzeichnisnamens - Sie werden von der Befehlssubstitution entfernt. Um dies zu umgehen, können Sie ein Nicht-Neuzeilen-Zeichen innerhalb der Befehlsersetzung anhängen - DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd && echo x)" - und entfernen Sie es ohne Befehlssubstitution - DIR="${DIR%x}" .

94 Stimmen

@jpmc26 Es gibt zwei sehr häufige Situationen: Unfälle und Sabotage. Ein Skript sollte nicht auf unvorhersehbare Weise versagen, nur weil jemand, irgendwo, eine mkdir $'\n' .

36 Stimmen

Wer Leute sein System auf diese Weise sabotieren lässt, sollte es nicht der Bash überlassen, solche Probleme zu erkennen... und schon gar nicht Leute einstellen, die zu solchen Fehlern fähig sind. Ich habe in den 25 Jahren, in denen ich die Bash benutze, noch nie erlebt, dass so etwas irgendwo passiert.... Deshalb gibt es Dinge wie Perl und Praktiken wie Taint Checking (ich werde wahrscheinlich dafür geflamed werden, dass ich das sage :)

2voto

Alexander Mills Punkte 76733

Wenn Ihr Bash-Skript ein Symlink ist dann ist dies der richtige Weg:

#!/usr/bin/env bash

dirn="$(dirname "$0")"
rl="$(readlink "$0")";
exec_dir="$(dirname $(dirname "$rl"))";
my_path="$dirn/$exec_dir";
X="$(cd $(dirname ${my_path}) && pwd)/$(basename ${my_path})"

X ist das Verzeichnis, das Ihr Bash-Skript enthält (die Originaldatei, nicht der Symlink). Ich schwöre bei Gott, dass dies funktioniert, und es ist der einzige mir bekannte Weg, dies richtig zu tun.

0voto

todd_dsm Punkte 740

Ich denke, die einfachste Antwort ist eine Parametererweiterung der ursprünglichen Variablen:

#!/usr/bin/env bash

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
echo "opt1; original answer: $DIR"
echo ''

echo "opt2; simple answer  : ${BASH_SOURCE[0]%/*}"

Es sollte eine Ausgabe wie diese erzeugen:

$ /var/tmp/test.sh
opt1; original answer: /var/tmp

opt2; simple answer  : /var/tmp

Die Variablen-/Parametererweiterung ${BASH_SOURCE[0]%/*}" scheint viel einfacher zu pflegen zu sein.

0voto

Zombo Punkte 1

Hier ist eine reine Bash-Lösung

$ cat a.sh
BASENAME=${BASH_SOURCE/*\/}
DIRNAME=${BASH_SOURCE%$BASENAME}.
echo $DIRNAME

$ a.sh
/usr/local/bin/.

$ ./a.sh
./.

$ . a.sh
/usr/local/bin/.

$ /usr/local/bin/a.sh
/usr/local/bin/.

0voto

Das tue ich normalerweise:

LIBDIR=$(dirname "$(readlink -f "$(type -P $0 || echo $0)")")
source $LIBDIR/lib.sh

0voto

Top-Master Punkte 5094

Im Folgenden wird der Verzeichnispfad des Skripts in der Datei dir variabel.

(Es wird auch versucht, die Ausführung unter Cygwin in Windows).

Und schließlich läuft sie die my-sample-app mit allen Argumenten, die diesem Skript mit "$@" :

#!/usr/bin/env sh

dir=$(cd "${0%[/\\]*}" > /dev/null && pwd)

if [ -d /proc/cygdrive ]; then
    case "$(uname -s)" in
        CYGWIN*|MINGW32*|MSYS*|MINGW*)
            # We are under Windows, so translate path to Windows format.
            dir=$(cygpath -m "$dir");
            ;;
    esac
fi

# Runs the executable which is beside this script
"${dir}/my-sample-app" "$@"

0 Stimmen

Was ist "Windows PHP"? " PHP für Windows "? Oder WAMP ? Oder etwas anderes?

0 Stimmen

Mit Hilfe von weiterer Beitrag entfernt die Notwendigkeit für PHP (und prüft jetzt, ob es unter Windows läuft).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X