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

42voto

Pubguy Punkte 1

Damit wird das aktuelle Arbeitsverzeichnis auf Mac OS X v10.6.6 (Snow Leopard):

DIR=$(cd "$(dirname "$0")"; pwd)

0 Stimmen

Das funktioniert also nicht unter Linux?

41voto

Ich glaube nicht, dass es so einfach ist, wie andere es dargestellt haben. pwd funktioniert nicht, da das aktuelle Verzeichnis nicht unbedingt das Verzeichnis ist, in dem sich das Skript befindet. $0 hat auch nicht immer die nötigen Informationen. Betrachten Sie die folgenden drei Möglichkeiten, ein Skript aufzurufen:

./script

/usr/bin/script

script

Auf die erste und dritte Art $0 nicht über die vollständigen Pfadinformationen verfügt. In der zweiten und dritten, pwd funktioniert nicht. Die einzige Möglichkeit, das Verzeichnis auf die dritte Art zu erhalten, wäre, den Pfad zu durchlaufen und die Datei mit der richtigen Übereinstimmung zu finden. Im Grunde müsste der Code wiederholen, was das Betriebssystem tut.

Eine Möglichkeit, das zu tun, was Sie wollen, wäre, die Daten einfach in der /usr/share und referenzieren Sie es über seinen vollständigen Pfad. Die Daten sollten sich nicht in der /usr/bin Das ist also wahrscheinlich die richtige Vorgehensweise.

9 Stimmen

Wenn Sie seinen Kommentar widerlegen wollen, müssen Sie anhand eines Codebeispiels beweisen, dass ein Skript auf den Speicherort zugreifen KANN.

39voto

test11 Punkte 1
$(dirname "$(readlink -f "$BASH_SOURCE")")

0 Stimmen

Ich bevorzuge, $BASH_SOURCE über $0 weil es auch für Leser, die sich nicht gut mit der Bash auskennen, verständlich ist. $(dirname -- "$(readlink -f -- "$BASH_SOURCE")")

0 Stimmen

Auch, $BASH_SOURCE funktioniert, während $0 nicht im Falle meines .bashrc (wobei sowohl Symlink als auch Sourcing verwendet werden)

29voto

Steve Baker Punkte 4217

Dies ist Linux-spezifisch, aber Sie könnten es verwenden:

SELF=$(readlink /proc/$$/fd/255)

1 Stimmen

Es ist auch Bash-spezifisch, aber vielleicht hat sich das Verhalten der Bash geändert? /proc/fd/$$/255 scheint auf den Tty zu zeigen, nicht auf ein Verzeichnis. Zum Beispiel verweisen in meiner aktuellen Login-Shell die Dateideskriptoren 0, 1, 2 und 255 alle auf /dev/pts/4 . In jedem Fall erwähnt das Bash-Handbuch fd 255 nicht, so dass es wahrscheinlich unklug ist, sich auf dieses Verhalten zu verlassen.

3 Stimmen

Interaktive Shell != Skript. Auf jeden Fall realpath ${BASH_SOURCE[0]}; scheint der beste Weg zu sein.

27voto

Atul Punkte 1959

Der kürzeste und eleganteste Weg, dies zu tun, ist:

#!/bin/bash
DIRECTORY=$(cd `dirname $0` && pwd)
echo $DIRECTORY

Das würde auf allen Plattformen funktionieren und ist super sauber.

Weitere Einzelheiten finden Sie in " In welchem Verzeichnis befindet sich das Bash-Skript? ".

1 Stimmen

Eine sehr saubere Lösung, die jedoch nicht funktioniert, wenn die Datei mit einem Symlink versehen ist.

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