
Gibt der Befehl pwd
in einem Shell-Skript das Verzeichnis aus, in dem sich das Shell-Skript befindet?
Antwort1
Hier sind drei unabhängige „Verzeichnisse“ im Spiel:
- 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 und es unter /tmp/pwd.sh speichern. Es enthält:
#!/bin/sh
pwd
cd /var
pwd
Sie können dann Ihr Passwort (Nr. 1 oben) in / ändern:
cd /
und führen Sie das Skript aus:
/tmp/pwd.sh
Dies beginnt mit der Anzeige Ihres vorhandenen Passworts (#1), ändert es dann in /var und zeigt es erneut an (#2). Keines dieser beiden pwd
's war "/tmp", das Verzeichnis, das /tmp/pwd.sh enthält (#3).
Antwort2
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 Beendigungsstatus zwischen 0 und 255 zurück. Das ist axiomatisch, aber im Allgemeinen nicht das, was die Leute meinen, wenn sie diese Art von Fragen stellen.
Zweitens pwd
ist beides einIntegrierte Bourne-Shellund eine Standard-Systembinärdatei. Entweder einedrucktdie logische oder physischeaktuelles Arbeitsverzeichnis, was im Allgemeinen ist:
- Ihre Position in der Verzeichnisstruktur, wenn Sie ein Skript oder eine Binärdatei aufrufen.
- Ihr aktueller Standort nach dem Ändern des Arbeitsverzeichnisses mitCDoder andere Dienstprogramme und integrierte Funktionen, die das aktuelle Arbeitsverzeichnis ändern, wie etwa pushd oder popd.
Wenn Sie das Verzeichnis des aktuellen Skripts möchten, verwenden Sie das dirname
Dienstprogramm wie im letzten Abschnitt unten beschrieben.
Schnelltest vonpwd
Als schneller Test, um zu sehen, wasPasswortwirklich 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
Dies wird ausgeben /etc
, nicht /tmp
, da Ihr aktuelles Arbeitsverzeichnis derzeit ist /etc
. Dies ist das erwartete Verhalten.
Abrufen des Verzeichnisses, das ein Skript enthält
Sie stellen diese Frage wahrscheinlich, weil Sie das Verzeichnis des aktuellen Skripts finden möchten. Im Allgemeinen ist Folgendes die schnelle und einfache Lösung:
#!/usr/bin/env bash
echo $(dirname "$0")
Dies funktioniert, weil $0
es im Allgemeinen den Pfadnamen enthält, der zum Aufrufen des ausgeführten Skripts verwendet wird, und die Shell-Erweiterung verwendet das dirname
Dienstprogramm, um den Pfad ohne den Dateinamenteil zurückzugeben. Mit der Bash-Parametererweiterung können Sie etwas Ähnliches, aber weniger portabel tun "${0%/*}"
.
Dies ist natürlich alles eine enorme Vereinfachung. Bitte lesen Sie dieBash-Handbuch(insbesondere die Abschnitte über Positionsparameter, Spezialparameter undBASH_QUELLE) und die Manpages für readlink
und realpath
um ein umfassenderes Verständnis der Randfälle zu erhalten, von denen es mehrere gibt.
Beim alltäglichen Skripting $0
reicht jedoch die Verzeichniskomponente von aus, um Ihnen das zu sagen, was Sie wissen möchten. Wenn Sie etwas tun, das kompliziert genug ist, $0
enthält where nicht die Informationen, die Sie tatsächlich benötigen, und Sie kompliziertere Konstrukte benötigen, wie:
echo $(dirname "$(realpath "$0")")
dann machen Sie sich das Leben wahrscheinlich unnötig schwerer.
Antwort3
pwd
Gibt 0 zurück, es sei denn, das aktuelle 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
Antwort4
Es gibt das Verzeichnis zurück, aus dem es aufgerufen/ausgeführt wird und nicht, wo sich das Skript befindet!
Hier ist try.sh:
echo "The current working directory: $PWD"
Diese Ausgabe macht es deutlicher:
[akarpe@ADM-PROD-OMNI ~]$ sh try.sh
The current working directory: /mnt/home/akarpe
[akarpe@ADM-PROD-OMNI ~]$ sh try/try.sh
The current working directory: /mnt/home/akarpe
[akarpe@ADM-PROD-OMNI ~]$ sh ./try.sh
The current working directory: /mnt/home/akarpe
[akarpe@ADM-PROD-OMNI ~]$ sh ./try/try.sh
The current working directory: /mnt/home/akarpe
[akarpe@ADM-PROD-OMNI ~]$ cd try
[akarpe@ADM-PROD-OMNI try]$ sh ./try.sh
The current working directory: /mnt/home/akarpe/try
[akarpe@ADM-PROD-OMNI try]$ sh ../try.sh
The current working directory: /mnt/home/akarpe/try