Ich schreibe ein Bash-Skript. Das aktuelle Arbeitsverzeichnis muss immer das Verzeichnis sein, in dem sich das Skript befindet.
Das Standardverhalten ist, dass das aktuelle Arbeitsverzeichnis im Skript das der Shell ist, von der aus ich es ausführe, aber ich möchte dieses Verhalten nicht.
myscript path/to/file
erwarte ich, dass das Skript den Pfad / zur / Datei relativ zu MEINEM aktuellen Verzeichnis auswertet, nicht zu dem Verzeichnis, in dem das Skript ausgeführt wird Was wäre für ein Skript passiert, mit demssh remotehost bash < ./myscript
in den BASH-FAQ erwähnt wird?cd "${BASH_SOURCE%/*}" || exit
Antworten:
quelle
$0
. In Ihrem Skript können Sie beispielsweise erwarten, dass Sie../../
sich auf das Verzeichnis zwei Ebenen über dem Speicherort des Skripts beziehen. Dies ist jedoch nicht unbedingt der Fall, wenn symbolische Links im Spiel sind../script
,.
ist es das richtige Verzeichnis, und wenn Sie.
es ändern, wird es auch in dem Verzeichnisscript
gespeichert, in dem es sich befindet, dh im aktuellen Arbeitsverzeichnis.bash script.sh
,$0
lautet der Wert vonscript.sh
. Dercd
Befehl "funktioniert" nur, wenn Sie sich nicht um fehlgeschlagene Befehle kümmern. Wenn Sieset -o errexit
(akaset -e
:) verwenden würden, um sicherzustellen, dass Ihr Skript nicht an fehlgeschlagenen Befehlen vorbeigeht, würde dies NICHT funktionieren, dacd script.sh
es sich um einen Fehler handelt. Der zuverlässige [Bash-spezifische] Weg istcd "$(dirname ${BASH_SOURCE[0]})"
Folgendes funktioniert auch:
Die Syntax wird in dieser StackOverflow-Antwort ausführlich beschrieben .
quelle
bash script.sh
-$0
wird nur der Name der DateiProbieren Sie die folgenden einfachen Einzeiler aus:
Für alle UNIX / OSX / Linux
Bash
Hinweis: Ein doppelter Bindestrich (-) wird in Befehlen verwendet, um das Ende der Befehlsoptionen anzuzeigen, sodass Dateien mit Bindestrichen oder anderen Sonderzeichen den Befehl nicht beschädigen.
Hinweis: Verwenden Sie
${BASH_SOURCE[0]}
in Bash zugunsten von$0
, da sonst der Pfad bei der Beschaffung unterbrochen werden kann (source
/.
).Für Linux, Mac und andere * BSD:
Hinweis:
realpath
Sollte standardmäßig in der beliebtesten Linux-Distribution (wie Ubuntu) installiert sein, in einigen Fällen kann es jedoch fehlen, sodass Sie es installieren müssen.Hinweis: Wenn Sie Bash verwenden, verwenden Sie
${BASH_SOURCE[0]}
zugunsten von$0
, da sonst der Pfad bei der Beschaffung unterbrochen werden kann (source
/.
).Andernfalls können Sie so etwas ausprobieren (es wird das erste vorhandene Tool verwendet):
Für Linux spezifisch:
Verwenden des GNU-Readlinks auf * BSD / Mac:
Hinweis: Sie müssen
coreutils
installiert haben (z. B. 1. Homebrew installieren , 2.brew install coreutils
).In Bash
In bash können Sie Parametererweiterungen verwenden , um dies zu erreichen, wie zum Beispiel:
Es funktioniert jedoch nicht, wenn das Skript aus demselben Verzeichnis ausgeführt wird.
Alternativ können Sie die folgende Funktion in bash definieren:
Diese Funktion benötigt 1 Argument. Wenn das Argument bereits einen absoluten Pfad hat, drucken Sie es so wie es ist, andernfalls drucken Sie das
$PWD
Argument Variable + Dateiname (ohne./
Präfix).oder hier ist die Version aus der Debian-
.bashrc
Datei:Verbunden:
Wie erkenne ich das aktuelle Verzeichnis, in dem ich mein Shell-Skript ausführe?
Rufen Sie das Quellverzeichnis eines Bash-Skripts aus dem Skript selbst ab
Absoluter Pfad des Bash-Skripts unter OS X.
Zuverlässige Möglichkeit für ein Bash-Skript, den vollständigen Pfad zu sich selbst zu erhalten
Siehe auch:
Wie kann ich das Verhalten von GNUs readlink -f auf einem Mac ermitteln?
quelle
cp
Befehl @kenorb?--
Befehlen wird ein doppelter Bindestrich ( ) verwendet, um das Ende der Befehlsoptionen anzuzeigen, damit Dateien, die Bindestriche oder andere Sonderzeichen enthalten, den Befehl nicht beschädigen. Versuchen Sie beispielsweise, die Datei übertouch "-test"
und zu erstellentouch -- -test
, und entfernen Sie sie dann überrm "-test"
undrm -- -test
, und sehen Sie den Unterschied.realpath
Paket veraltet ist, nicht GNUrealpath
. Wenn Sie der Meinung sind, dass dies nicht klar ist, können Sie eine Bearbeitung vorschlagen.Es ist einfach. Es klappt.
quelle
cd "${BASH_SOURCE%/*}" || exit
Die akzeptierte Antwort eignet sich gut für Skripte, die an keiner anderen Stelle verknüpft wurden, z. B. in
$PATH
.Wenn das Skript jedoch über einen Symlink ausgeführt wird,
Dies wird in das
~/bin/
Verzeichnis und nicht in das Verzeichnis~/project/
verschoben, wodurch Ihr Skript wahrscheinlich beschädigt wird, wenn der Zweck von darincd
besteht, Abhängigkeiten in Bezug auf einzuschließen~/project/
Die symlink sichere Antwort ist unten:
readlink -f
ist erforderlich, um den absoluten Pfad der möglicherweise verknüpften Datei aufzulösen.Die Anführungszeichen sind erforderlich, um Dateipfade zu unterstützen, die möglicherweise Leerzeichen enthalten können (schlechte Vorgehensweise, aber es ist nicht sicher anzunehmen, dass dies nicht der Fall ist).
quelle
Dieses Skript scheint für mich zu funktionieren:
Die pwd-Befehlszeile gibt den Speicherort des Skripts als aktuelles Arbeitsverzeichnis wieder, unabhängig davon, von wo aus ich es ausführe.
quelle
realpath
ist unwahrscheinlich, überall installiert zu werden. Was je nach Situation des OP möglicherweise keine Rolle spielt.realpath
aber es hat,readlink
was ähnlich zu sein scheint.Holen Sie sich den richtigen Weg zu Ihrem Skript
(Dies ist die Antwort auf meine Frage hier: Holen Sie sich den Namen des Verzeichnisses, in dem ein Skript ausgeführt wird. )
quelle
quelle
PWD ist eine Umgebungsvariable.
quelle
Wenn Sie nur das aktuelle Arbeitsverzeichnis drucken müssen, können Sie diesem folgen.
Ausführungsberechtigung erteilen:
Führen Sie dann das Skript aus, bis
./test
Sie das aktuelle Arbeitsverzeichnis sehen können.quelle
pwd
? Scheint mir eine Menge verschwendeter Tastendrücke zu sein.