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 :)

7voto

l0b0 Punkte 51652

Keine der derzeitigen Lösungen funktioniert, wenn sich am Ende des Verzeichnisnamens Zeilenumbrüche befinden - diese werden von der Befehlssubstitution entfernt. Um dies zu umgehen, können Sie innerhalb der Befehlssubstitution ein Zeichen anhängen, das kein Zeilenumbruch ist, und dann nur dieses Zeichen entfernen:

dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd && echo x)"
dir="${dir%x}"

Dies schützt vor zwei sehr häufigen Situationen: Unfälle und Sabotage. Ein Skript sollte nicht auf unvorhersehbare Weise versagen, nur weil jemand, irgendwo, eine mkdir $'\n' .

6voto

alanwj Punkte 523

Verwenden Sie eine Kombination aus readlink um den Namen zu kanonisieren (mit dem Bonus, dass er zu seiner Quelle zurückverfolgt wird, wenn es sich um einen Symlink handelt) und Verzeichnisname um den Verzeichnisnamen zu extrahieren:

script="`readlink -f "${BASH_SOURCE[0]}"`"
dir="`dirname "$script"`"

6voto

tigfox Punkte 1

Keine der anderen Antworten funktionierte bei einem Bash-Skript, das von Finder en OS X . Ich habe es schließlich benutzt:

SCRIPT_LOC="`ps -p $$ | sed /PID/d | sed s:.*/Network/:/Network/: |
sed s:.*/Volumes/:/Volumes/:`"

Es ist nicht schön, aber es erfüllt seinen Zweck.

6voto

BuvinJ Punkte 8973

Das hat bei mir funktioniert, während die anderen Antworten hier nicht funktionierten:

thisScriptPath=`realpath $0`
thisDirPath=`dirname $thisScriptPath`
echo $thisDirPath

3 Stimmen

Beachten Sie, dass es nicht notwendig ist, auf Echo zurückzugreifen. Einfaches Aufrufen von dirname gibt den Verzeichnisnamen aus. Und in diesem Fall führt der Aufruf von echo ohne korrekte Anführungszeichen der Variablen möglicherweise zu einer anderen Ausgabe, da Leerzeichen unterdrückt werden. Insgesamt ist es sauberer, einfach zu schreiben dirname "$(realpath "$0")"

0 Stimmen

Sie haben recht, dass dies in einer einzigen Zeile zusammengefasst werden kann. Die Aufteilung in einzelne Variablen dient der Veranschaulichung und Selbstdokumentation. Die Echo-Zeile ist nur p.o.c. da.

0 Stimmen

Ich bin mir ziemlich sicher, dass sie das tut (wenn ich mich richtig erinnere). Beachten Sie, dass verschiedene Nix-Distributionen und Kontexte, wie Sie sie ansprechen (z.B. Linux vs. Mac vs. Cygwin...bash vs. dash...), all dies etwas anders handhaben. Das ist der Grund, warum es SOO viele Antworten in diesem Thread gibt! Sie müssen Ihren Anwendungsfall testen, um das zu bestätigen. Ich wünschte, es gäbe eine solide, plattform-/kontextübergreifende Antwort auf diese einfache Frage!

5voto

cdonat Punkte 2710

Ich verwende normalerweise:

dirname $(which $BASH_SOURCE)

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