Auf meinem Server habe ich eine Verzeichnisstruktur, die ungefähr so aussieht:
/myproject/code
Normalerweise habe ich eine SSH-Verbindung zum Server und 'stehe' in diesem Verzeichnis:
root@machine:/myproject/code#
Wenn ich eine neue Version meines Codes bereitstelle, wird das Codeverzeichnis entfernt.
root@machine:/myproject/code# ./run
-bash: ./run: No such file or directory
Und die einzige Lösung, die ich gefunden habe, ist das Aus- und Einspielen von CDs:
root@machine:/myproject/code# cd ../code
root@machine:/myproject/code# ./run
Running...
Kann ich das vermeiden? Es ist ein etwas merkwürdiges Verhalten. Wenn Sie eine nette Erklärung haben, warum dies passiert, würde ich es begrüßen.
shell
command-line
directory
cd-command
Markus Johansson
quelle
quelle
run
mit dem alten Verzeichnis identisch ist. Es hat nur denselben Namen und dasselbe übergeordnete Verzeichnis. Vergleichen Sie dies damit, dass Sie Ihr altes Auto zerkleinern und ein neues Auto mit genau der gleichen Farbe und dem gleichen Modell kaufen: Sie möchten nicht im zerkleinerten Auto sitzen und hoffen, dass Sie unversehrt auf dem neuen landen, oder?cd ../code
ist kein Noop...
ist eine Verknüpfung für das übergeordnete Element des Pfads, den Sie haben oder früher hatten. Wenn Ihr aktuelles Verzeichnis gelöscht wird, ist der übergeordnete Pfad möglicherweise noch vorhanden und in diesem Fall durch Auswerten erreichbar..
. In diesem Verzeichnis wird nach einem Verzeichnis mit dem Namen 'code' gesucht.Antworten:
Da Dateien und Verzeichnisse im Grunde genommen Inodes von Dateisystemen sind , keine Namen - dies ist möglicherweise ein Implementierungsdetail, das für den Dateisystemtyp spezifisch ist, aber es gilt für alle ext-Systeme, also werde ich mich hier daran halten.
Wenn ein neues Verzeichnis
code
erstellt wird, ist es mit einem neuen Inode verknüpft, und dort befindet es sich. Es gibt keine Aufzeichnungen über zuvor gelöschte Dateien und Verzeichnisse, so dass das System nicht überprüfen kann, welchen Inode es verwendet hat, um Dinge zu belegen und möglicherweise zu mischen, damit es wieder dasselbe ist. Ein solches System würde schnell unbrauchbar werden und in jedem Fall ist es wahrscheinlich keine Garantie, dass Sie wieder da sind - das wäre unerwünscht, da Sie auch versehentlich woanders landen könnten, wenn ein Verzeichnis erstellt wird das nimmt Ihre (derzeit unbenutzte) Inode.Ich bin nicht sicher, ob diese letzte Möglichkeit besteht oder ob der Inode des gelöschten Verzeichnisses, das Ihrem aktuellen Arbeitsverzeichnis zugewiesen ist, verfolgt wird, sodass ihm für die Dauer usw. nichts zugewiesen wird.
quelle
Ihre Shell führt nicht jedes Mal einen
cd
Befehl an dem Pfad aus, in dem sie sich während des letzten Befehls befunden hat, bevor der nächste Befehl ausgeführt wird.Sie haben das aktuelle Verzeichnis gelöscht und ein Verzeichnis mit demselben Namen erstellt, bei dem es sich nicht um dasselbe Verzeichnis handelt, sondern nur um etwas mit demselben Namen / Pfad.
Dateibrowser wie Nautilus und Windows Explorer "gehen" normalerweise in der Verzeichnisstruktur nach oben, wenn ein Verzeichnis in einem lokalen Dateisystem gelöscht wird. Dies gilt jedoch nicht immer für vernetzte Dateisysteme. In diesem Fall wird das Löschen manchmal nicht bemerkt und das erneute Auftreten kann dazu führen, dass Sie in das neue Verzeichnis gelangen.
Eine Shell könnte
cd
vor dem Ausführen des nächsten Befehls in das aktuelle Verzeichnis gelangen, mir sind keine bekannt, die dies tun (oder dafür konfiguriert werden können).quelle
Auf den meisten UNIX-ähnlichen Systemen wird das "aktuelle Verzeichnis" für einen Prozess im Kernel als Dateideskriptor gespeichert, der auf dieses Verzeichnis verweist. Der Kernel speichert nicht den Pfad des aktuellen Verzeichnisses: Diese Informationen werden von Ihrer Shell verfolgt.
Ein Dateisystemobjekt (Datei oder Verzeichnis) wird nur dann endgültig zerstört, wenn alle Dateisystemverknüpfungen zu diesem Objekt verschwunden sind und keine Dateideskriptoren auf dieses Objekt verweisen.
Wenn also ein Verzeichnis entfernt wird, während es noch einen Prozess gibt, der es als aktuelles Arbeitsverzeichnis enthält, verhindert der Prozess,
cwd
dass das Verzeichnis wirklich gelöscht wird. Die Dateisystemverknüpfungen, die das Verzeichnis verankern (sein Eintrag im übergeordneten Verzeichnis und sein gesamter Inhalt), gehen verloren, aber das Verzeichnis selbst wird weiterhin als eine Art "Zombie" existieren. In der Zwischenzeit können Sie ein brandneues Verzeichnis am selben Speicherort wie das alte erstellen, bei dem es sich um ein völlig anderes Dateisystemobjekt handelt, das jedoch denselben Pfad aufweist.Wenn Sie dies tun
cd ../code
(oder auf vielen Shellscd .
), durchlaufen Sie tatsächlich die Dateisystemhierarchie und wechseln in das neue Verzeichnis, das sich an der alten Adresse befindet.In analoger Weise würde das Entfernen eines Verzeichnisses bedeuten, dass ein Haus gewaltsam auf die Müllkippe verschoben wird (wodurch die Bindung zur vorherigen Adresse unterbrochen wird). Wenn dort noch jemand lebte (der es als sein Eigentum benutzt
cwd
), musste er gehen, bevor das Haus zerstört werden konnte. In der Zwischenzeit könnte ein brandneues Haus an der alten Adresse gebaut werden.quelle
@Anthon hat Gründe geklärt, warum es passiert
Als Lösung können Sie einen Alias verwenden , zum Beispiel:
Aliase für bash werden in ~ / .bashrc gespeichert
quelle
Bestätigen Das aktuelle Arbeitsverzeichnis basiert auf der Inode-Nummer und nicht auf dem, wonach Sie gesucht haben, um dorthin zu gelangen. Da Sie bash verwenden, können Sie $ PWD wie folgt verwenden, um in das neue Verzeichnis mit dem gleichen Namen zu wechseln:
cd $ PWD
Zur Veranschaulichung habe ich einen Dummy-Bereitstellungsbefehl erstellt:
Hat die erste Bereitstellung erstellt, eine CD zum Codieren erstellt und dann den Inhalt mit überprüft,
ls -lai
damit Sie die Inodes sehen können:Führen Sie nun die zweite Bereitstellung aus
Und überprüfe den Inhalt des Verzeichnisses ... jetzt ist nichts mehr im Verzeichnis! nicht mal '.' und '..'! Daran können Sie erkennen, dass die Bash den Verzeichniseintrag
cd ..
'..' nicht verwendet, wenn Sie sie ausführen, da '..' nicht mehr vorhanden ist - ich nehme an, dass dies Teil der $ PWD-Behandlung ist. Einige andere / ältere Shells funktionieren nichtcd ..
in dieser Situation , Sie müssen zuerst einen absoluten Pfad angeben.CD an
$PWD
und versuchen Sie es erneut:Beachten Sie, wie sich der Inode für das aktuelle Verzeichnis (.) Geändert hat.
Wenn Ihr Bereitstellungsskript das alte Verzeichnis in einen anderen Namen verschieben würde, z. B.
mv code code.$$
im obigen Bereitstellungsskript,./run
würde dies funktionieren, aber bis Sie es verwendencd $PWD
, würden Sie den alten Code ausführen, nicht den neuen.Die Bereitstellung mit capistrano hat das gleiche Problem (sie haben einen Symlink vom aktuellen Namen zur aktuellen Version), daher verwende ich Aliase, um zu den Produktions- / Staging-Bereichen zu wechseln und RAIL_ENV entsprechend einzustellen:
quelle
Der Weg zu etwas ist, wie man dorthin kommt, nicht das Ding selbst. Der Weg zu Ihrem Bett führt vielleicht durch Ihr Zimmer, aber wenn Sie im Bett sind und jemand es aufhebt und es nach draußen trägt, sind Sie nicht mehr in Ihrem Zimmer.
quelle
Keine in sich geschlossene Antwort, aber ich habe einen zusätzlichen Punkt, für den der Kommentarbereich zu klein war.
Um ein besseres Gefühl dafür zu bekommen, dass ein Verzeichnis in den relevanten Dateisystemen mehr als nur ein Pfad ist, verschieben Sie das aktuelle Arbeitsverzeichnis eines anderen Prozesses: Starten Sie in einer Shell eine interaktive Python-Sitzung:
Wechseln Sie dann zu einer anderen Shell und verschieben Sie das Verzeichnis:
Zurück zum Original:
quelle