Ich verstehe den Begriff der Hardlinks sehr gut und habe die Manpages für grundlegende Tools wie cp
--- und sogar die neuesten POSIX-Spezifikationen --- einige Male gelesen . Trotzdem war ich überrascht, folgendes Verhalten zu beobachten:
$ echo john > john
$ cp -l john paul
$ echo george > george
Zu diesem Zeitpunkt hat john
und paul
den gleichen Inode (und Inhalt) und george
unterscheidet sich in beiden Punkten. Jetzt machen wir:
$ cp george paul
Zu diesem Zeitpunkt erwartete george
und erwartete paul
ich unterschiedliche Inode-Nummern, aber den gleichen Inhalt - diese Erwartung wurde erfüllt -, aber ich erwartete auch, dass paul
jetzt eine andere Inode-Nummer als john
und john
der Inhalt noch vorhanden sein würde john
. Hier war ich überrascht. Es stellt sich heraus, dass das Kopieren einer Datei in den Zielpfad paul
auch dazu führt, dass dieselbe Datei (derselbe Inode) auf allen anderen Zielpfaden installiert wird, die den paul
Inode gemeinsam nutzen. Ich dachte, dass cp
erstellt eine neue Datei und verschiebt es an die Stelle, die zuvor von der alten Datei besetzt war paul
. Stattdessen scheint es so zu sein, dass die vorhandene Datei geöffnet paul
, abgeschnitten und geschrieben wirdgeorge
's Inhalt in die vorhandene Datei. Daher werden alle "anderen" Dateien mit demselben Inode "ihren" Inhalt gleichzeitig aktualisiert.
Ok, dies ist ein systematisches Verhalten, und jetzt, da ich weiß, dass ich es erwarten kann, kann ich herausfinden, wie ich es umgehen oder wie es angebracht ist, es auszunutzen. Was mich verwirrt, ist, wo ich dieses Verhalten dokumentiert sehen sollte? Es würde mich wundern, wenn es nicht irgendwo in Dokumenten dokumentiert ist, die ich mir bereits angesehen habe. Aber anscheinend habe ich es verpasst und kann jetzt keine Quelle finden, die dieses Verhalten beschreibt.
cp
dokumentiert, dass es die Zieldatei überschreibt, wenn die Zieldatei bereits vorhanden ist. Sie haben Recht, dass nicht im Detail angegeben wird, was "Überschreiben" bedeutet, aber definitiv "Überschreiben", nicht "Ersetzen". Wenn Sie pedantisch sein wollen, können Sie argumentieren, dass "Überschreiben" genau das ist, wascp
tut, und das erwartete Verhalten würde zu Recht als "Ersetzen" bezeichnet.Beachten Sie auch, dass, wenn
cp
bereits vorhandene Zieldateien "ersetzt" würden, dies vernünftigerweise als überraschend oder falsch angesehen werden könnte, wahrscheinlich mehr als "überschreiben". Beispielsweise:cp
zuerst die alte Datei gelöscht und dann eine neue erstellt würde, gäbe es ein Zeitintervall, in dem die Datei nicht vorhanden wäre, was überraschend wäre.cp
zuerst eine temporäre Datei erstellt und dann verschoben wird, sollte dies wahrscheinlich dokumentiert werden, da solche temporären Dateien mit seltsamen Namen gelegentlich bemerkt werden ... aber nicht.cp
aufgrund von Berechtigungen keine neue Datei im selben Verzeichnis wie die alte Datei erstellt werden konnte, ist dies unglücklich (insbesondere, wenn die alte Datei bereits gelöscht wurde).cp
und der Benutzer, der sie ausführt,cp
nicht,root
ist es unmöglich, den Eigentümer und die Berechtigungen der neuen Datei mit denen der neuen Datei abzugleichen.cp
die nicht bekannt sind, gehen diese in der Kopie verloren. Heutzutage sollten Implementierungen voncp
zuverlässig Dinge wie erweiterte Attribute verstehen, aber das war nicht immer so. Und es gibt noch andere Dinge, wie MacOS Resource Forks oder für entfernte Dateisysteme im Grunde alles.Fazit: Jetzt wissen Sie, was
cp
wirklich funktioniert. Sie werden nie wieder überrascht sein! Ehrlich gesagt denke ich, dass mir vor vielen Jahren das gleiche passiert sein könnte.quelle
man
Seiten fürcp
BSD (zumindest OSX) und Gnu-Versionencp
nicht so explizit über "Überschreiben". Dieses Wort wird nur in den Kommentaren zu Optionen-i
und verwendet-n
. Die Gnu-Hilfeseite ist besonders wenigCopy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.
In the first synopsis form, the cp utility copies the contents of the source_file to the target_file.
‘cp’ copies files (or, optionally, directories). The copy is completely independent of the original.
Ich sehe, dass der POSIX 2013-Standard das beobachtete Verhalten spezifiziert . Es sagt:
quelle
cp
dass das Ziel ähnliche Ergebnissemv
liefert und alle Hardlinks unterbricht, zu denen es gehört. Aber jetzt, wo ich darüber nachdenke, würde das bedeuten, dass es spezifischunlink(2)
das Ziel (cp -f
) sein müsste oder ein anders benanntes temporäres Objekt erstellen müsste und dannrename(2)
. Die einfache Implementierung besteht darin, die Datei nur zum Überschreiben zu öffnen, was für POSIX erforderlich ist. Es ist gleichbedeutend mitcat src > dest
Wenn Sie sagen können: "Wenn Sie eine Datei in den Zielpfad kopieren, wird
paul
dieselbe Datei (derselbe Inode) auch in alle anderen Zielpfade kopiert, die denpaul
Inode gemeinsam haben." harte links sehr gut. Wenn ich Sir McCartney einen Apfel gebe, habe ich Paul einen Apfel gegeben, und ich habe John Lennons Songwriting-Partner einen Apfel gegeben. Aber ich habe nicht drei Äpfel ausgegeben; Ich habe einer Person, die mehrere Namen / Titel / Deskriptoren hat, einen Apfel gegeben.Ebenso, wenn Sie kopieren
george
zupaul
, sind Sie nicht auch kopieren esjohn
. Sie kopieren diegeorge
Daten vielmehr in die Datei, auf deren Inode derpaul
Verzeichniseintrag verweist.Schritt für Schritt: Wenn Sie es tun
Sie haben eine neue Datei erstellt (vorausgesetzt,
john
in diesem Verzeichnis wurde noch keine Datei benannt ). Genauerjohn
gesagt wird davon ausgegangen, dass sich noch kein Verzeichniseintrag mit dem Namen in diesem Verzeichnis befindet (da sich streng genommen keine Dateien in Verzeichnissen befinden, sondern nur Verzeichniseinträge, die auf Inodes verweisen). Nachdem du es getan hastoder
Sie haben keine neue Datei erstellt. Stattdessen haben Sie Ihrer vorhandenen Datei einen neuen Namen gegeben. Sie haben jetzt eine Datei mit zwei Namen:
john
undpaul
. Und wenn du sagstSie überschreiben diese Datei . Die Tatsache, dass es zwei Namen hat, ist irrelevant; es könnte 42 Namen haben, möglicherweise an Stellen, auf die Sie nicht einmal zugreifen können, und dieser Befehl würde die
george\n
Daten nicht in alle diese Namen (Pfade) kopieren ; Es werden lediglich die Daten in eine Datei mit mehreren Namen kopiert .quelle
john
undpaul
beginne als zwei Pfadnamen für dieselbe Datei. Aber es war der einfachste Weg, mich auszudrücken. Ich denke nicht, dass die bloße Vorstellung einer festen Verbindung, richtig verstanden, eines der beiden Verhaltensweisen für (ohne ) diktiert .cp
-l