Merkwürdiger Unterschied zwischen pwd und / bin / pwd

15

Ich habe dem aktuellen Verzeichnis mit einen Symlink hinzugefügt ln -s . aa. Wenn ich ausführe cd aaund danach ausführe , pwdlautet die Antwort /home/sim/aa.

Aber wenn ich /bin/pwdes drucke /home/sim(das aktuelle Verzeichnis hat sich nicht geändert).

Woher kommt dieser Unterschied?

user3581976
quelle

Antworten:

17

In den meisten Shells, einschließlich Bash, pwdist eine Shell eingebaut:

$ type -a pwd
pwd is a shell builtin
pwd is /bin/pwd

Wenn Sie verwenden /bin/pwd, müssen Sie die -LOption verwenden, um dasselbe Ergebnis wie builtin zu erhalten pwd:

$ ln -s . test
$ cd test && pwd
/home/cuonglm/test
$ /bin/pwd
/home/cuonglm
$ /bin/pwd -L
/home/cuonglm/test

/bin/pwdIgnoriert standardmäßig Symlinks und druckt das aktuelle Verzeichnis.

Von info pwd:

`-L'
`--logical'
     If the contents of the environment variable `PWD' provide an
     absolute name of the current directory with no `.' or `..'
     components, but possibly with symbolic links, then output those
     contents.  Otherwise, fall back to default `-P' handling.

`-P'
`--physical'
     Print a fully resolved name for the current directory.  That is,
     all components of the printed name will be actual directory
     names--none will be symbolic links.

Der eingebaute Link pwdenthält standardmäßig Symlinks , außer dass diese -POption verwendet wird oder -o physicaldie Option " Eingebaut setzen" aktiviert ist.

Von man bash:

pwd [-LP]
              Print the absolute pathname of the  current  working  directory.
              The pathname printed contains no symbolic links if the -P option
              is supplied or the -o physical option to the set builtin command
              is  enabled.  If the -L option is used, the pathname printed may
              contain symbolic links.  The return status is 0 unless an  error
              occurs  while  reading  the  name of the current directory or an
              invalid option is supplied.
cuonglm
quelle
Ich bin mir nicht sicher, woher diese Unterschiede kommen
user3581976
/bin/pwdIgnoriert standardmäßig Symlink, lies Teil info pwdmeiner Antwort: Gib einen vollständig aufgelösten Namen für das aktuelle Verzeichnis aus. Das heißt, alle Komponenten des gedruckten Namens sind tatsächliche Verzeichnisnamen - keine sind symbolische Links.
Cuonglm
@ user3581976: Siehe mein Update für mehr Klarheit.
Donnerstag,
Warum gibt es einen -L-Befehl für pwd, obwohl dieser standardmäßig festgelegt ist? Und verwendet die Shell nicht den Befehl / bin / pwd, um pwd auszuführen?
user3581976
2
@ user3581976: Das Bild, mit dem Sie Ihre Shell starten set -o physical, ist jetzt standardmäßig pwddie -POption use . Wenn Sie keine -LOption haben, wie drucken Sie den Pfad, der Symlink enthält? Lesen Sie dies, um https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.htmlzu wissen, was set -o physicalpassiert.
Donnerstag,
7

Es ist möglich, dass ein Prozess das Dateisystem abfragt, um sein aktuelles Arbeitsverzeichnis zu ermitteln. Dabei wird eine Methode verwendet, die etwas zu kompliziert ist, um als Antwort auf diese Frage zum Thema zu gelangen. Dies ist, was das pwdProgramm und die getcwdBibliotheksfunktion tun. In den Anfängen von Unix waren dies die einzigen Möglichkeiten, um herauszufinden, wie Ihr Arbeitsverzeichnis aussah. Hier ist der Teil der Antwort auf Ihre Frage, den ich in keiner der anderen Antworten oder an einer anderen Stelle auf dieser Website finden kann (nach einer Suche von 42 Sekunden):

  • Wenn die Shell gestartet wird, erhält sie ihr aktuelles Arbeitsverzeichnis (wahrscheinlich durch einen Aufruf getcwd).
  • Wenn Sie danach ein cd, pushdoder ausführenpopd , verfolgt die Shell das Arbeitsverzeichnis mithilfe von Zeichenfolgenmanipulationsfunktionen. Beispielsweise,

    • Wenn Ihr Arbeitsverzeichnis /home/simund Sie cd ..eingeben, berechnet die Shell, dass Ihr Arbeitsverzeichnis ist /home.
    • Wenn Ihr Arbeitsverzeichnis ist , /home/simund geben Sie cd .die Schale berechnet , dass Ihr Arbeitsverzeichnis noch ist /home/sim.
    • Wenn Ihr Arbeitsverzeichnis ist , /home/simund geben Sie cd aadie Schale berechnet , dass Ihr Arbeitsverzeichnis ist /home/sim/aa- ohne zu überprüfen, ob aaein symbolischer Link ist.

    Auf diese Weise werden die "Kosten" für Anrufe gespart getcwd. Dies ist jedoch ein Kompromiss, da dies zu falschen Informationen führen kann.

  • Der pwd(eingebaute) Befehl zeigt einfach die in der Shell gespeicherte / berechnete Vorstellung des Arbeitsverzeichnisses an.
  • Außerdem fügt die Shell ihre gespeicherte / berechnete Vorstellung des Arbeitsverzeichnisses zur Vereinfachung der Benutzerprozesse in die PWD-Umgebungsvariable ein . Ein Prozess sollte sich niemals darauf verlassen, wenn er genaue Informationen benötigt.

Unterm Strich kann die Shell also verwirrt werden, wo sie sich befindet. Wenn Sie jedoch etwas eingeben /bin/pwd, wird dies in einem separaten Prozess ausgeführt, der keinen Zugriff auf die Shell-Vorstellung des Arbeitsverzeichnisses hat und so das wahre Arbeitsverzeichnis selbst auf altmodische Weise bestimmt. (Ausnahme: Das /bin/pwdProgramm kann auf die PWD-Umgebungsvariable zugreifen, und dies scheint zu geschehen, wenn Sie dies angeben -L.) Hier ist ein weiteres Beispiel dafür, wie die Shell verwirrt werden kann:

cd /home/sim/aa # Es sei angenommen , dass /home, /home/simund /home/sim/aa
# sind alle realen Verzeichnisse (keine symbolischen Links).
pwd # Ausgabe:, /home/sim/aawas richtig ist.
mv ../aa ../bb
pwd # Ausgabe:, /home/sim/aawas falsch ist.
/bin/pwd # Ausgabe:, /home/sim/bbwas richtig ist.


Und nur für den Fall, dass Sie sich darüber nicht im Klaren sind, wenn Sie tippen ln -s . aaund sich cd aaIhr aktuelles Arbeitsverzeichnis nicht mehr ändert als beim Tippen cd .- denn genau das tun Sie beim Tippen cd aa.

Scott
quelle
Danke, sehr gute Antwort, darauf habe ich gewartet;)
user3581976
2
Diese Antwort scheint ein wenig verbogen zu sein . Es gibt mehr zu -Lals Kosteneinsparung - und $PWDist ein benutzerdefinierte POSIX-spezifizierten Umgebungsvariable - User-Space - Anwendungen sollten wahrscheinlich ihm vertrauen (was immer das bedeutet ...?) . Obwohl ich überhaupt kein Fan von Symlinks bin, ist es das Vorrecht des Benutzers, indirekt in so viele verrückte Richtungen zu gehen, wie er oder sie mit ihnen wählen sollte - und -Ldarum geht es mehr als alles andere.
mikeserv
1
Dies sollte die akzeptierte Antwort sein (die symbolischen Links sind nicht der Punkt der Frage).
Thomas Dickey