Hier spielen drei unabhängige "Verzeichnisse" eine Rolle:
- das aktuelle Arbeitsverzeichnis Ihrer aktuellen Shell,
- das aktuelle Arbeitsverzeichnis des Shell-Skripts und
- das Verzeichnis, das das Shell-Skript enthält.
Um zu demonstrieren, dass sie unabhängig sind, können Sie ein Shell-Skript schreiben, das unter /tmp/pwd.sh gespeichert wird und Folgendes enthält:
#!/bin/sh
pwd
cd /var
pwd
Sie können dann Ihr Passwort (Nr. 1 oben) in /:
änderncd /
und führen Sie das Skript aus:
/tmp/pwd.sh
Das beginnt mit der Demonstration Ihres vorhandenen pwd (#1), ändert es dann in /var und zeigt es erneut (#2). Keines von diesen pwd
's waren "/tmp", das Verzeichnis, das /tmp/pwd.sh (#3) enthält.
Aktuelles (oder aktuelles) Arbeitsverzeichnis
Gibt der Befehl pwd in einem Shell-Skript das Verzeichnis zurück, in dem sich das Shell-Skript befindet?
Nein.
Erstens gibt per Definition kein Shell-Skript oder Shell-Befehl etwas anderes als einen numerischen Exit-Status zwischen 0 und 255 zurück. Das ist selbstverständlich, aber im Allgemeinen nicht das, was Leute meinen, wenn sie diese Art von Fragen stellen.
Zweitens pwd
ist sowohl eine integrierte Bourne-Shell als auch eine Standardsystem-Binärdatei. Entweder man druckt das logische oder physische aktuelle Arbeitsverzeichnis , das ist im Allgemeinen:
- Ihre Position in der Verzeichnisstruktur, wenn Sie ein Skript oder eine Binärdatei aufrufen.
- Ihr aktueller Standort nach Wechsel des Arbeitsverzeichnisses mit cd oder andere Dienstprogramme und eingebaute Funktionen, die das aktuelle Arbeitsverzeichnis ändern, wie etwa pushd oder popd.
Wenn Sie das Verzeichnis des aktuellen Skripts möchten, verwenden Sie die dirname
Dienstprogramm, wie im letzten Abschnitt unten beschrieben.
Schnelltest von pwd
Als Schnelltest, um zu sehen, was pwd wirklich druckt, können Sie Folgendes ausführen:
# Create a shell script containing pwd.
cat <<-EOF > /tmp/test_pwd.sh
#!/bin/sh
pwd
EOF
# Make the script executable.
chmod 755 /tmp/test_pwd.sh
# Go somewhere on the filesystem, and call the test script.
cd /etc
/tmp/test_pwd.sh
Dadurch wird /etc
gedruckt , nicht /tmp
, da Ihr aktuelles Arbeitsverzeichnis derzeit /etc
ist . Dies ist das erwartete Verhalten.
Verzeichnis abrufen, das ein Skript enthält
Wahrscheinlich stellen Sie diese Frage, weil Sie das Verzeichnis des aktuellen Skripts finden möchten. Im allgemeinen Fall ist Folgendes die Quick-and-Dirty-Lösung:
#!/usr/bin/env bash
echo $(dirname "$0")
Das funktioniert, weil $0
enthält im Allgemeinen den Pfadnamen, der zum Aufrufen des ausgeführten Skripts verwendet wird, und die Shell-Erweiterung verwendet den dirname
Dienstprogramm, um den Pfad ohne den Teil des Dateinamens zurückzugeben. Etwas Ähnliches, aber weniger portabel, können Sie mit der Bash-Parametererweiterung "${0%/*}"
machen .
Das alles ist natürlich eine gewaltige Vereinfachung. Bitte lesen Sie das Bash-Handbuch (insbesondere die Abschnitte zu Positionsparametern, speziellen Parametern und BASH_SOURCE ) und die Manpages für readlink
und realpath
um ein umfassenderes Verständnis der Grenzfälle zu erhalten, von denen es mehrere gibt.
Bei der täglichen Skripterstellung ist jedoch die Verzeichniskomponente von $0
reicht aus, um dir zu sagen, was du wissen willst. Wenn Sie etwas kompliziert genug machen, wo $0
enthält nicht die Informationen, die Sie tatsächlich benötigen, und Sie benötigen kompliziertere Konstrukte wie:
echo $(dirname "$(realpath "$0")")
dann machen Sie sich wahrscheinlich das Leben schwerer als nötig.
pwd
gibt 0 zurück, es sei denn, sein aktuelles Arbeitsverzeichnis kann nicht geöffnet werden.
mkdir /tmp/d; cd "$_"
pwd && pwd -P; echo "$?"
rmdir ../d
pwd && pwd -P; echo "$?"
/tmp/d
/tmp/d
0
/tmp/d
pwd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
1