Warum benötigt das Unix-MV-Programm nicht die Option -R (rekursiv) für Verzeichnisse, sondern die Option cp?


58

Ich werde immer durcheinander gebracht, wenn ich etwas benutzen muss cpoder mv: "Brauche ich eine -ROption, wenn ich mit dir arbeite?" In GNU cpbraucht coreutils -Rund mvtut es nicht.

Ich kann einfach keinen Grund , warum cpbraucht -ROption Verz zum Kopieren und mvdies nicht tut. Ich denke, dass cpdirs ohne -R(aber rekursiv zu verhalten, wie es gibt -Rund wie es mvtut) keine Probleme verursachen würden, außer jemandes Gewohnheiten bei der Verwendung des Werkzeugs zu brechen.

Kennen Sie eine Erklärung? Vielleicht hatte es einen Grund vor langer Zeit?


Zusätzliche Frage: Warum cperstellen Coreutils-Entwickler standardmäßig keine rekursiven Kopierverzeichnisse?

Antworten:


45

Ein Verzeichnis ist (konzeptionell) eine spezielle "Datei", die eine Liste von Namen und die Inode-Nummern enthält, auf die diese Namen verweisen. Einige Namen können Unterverzeichnisse sein. Es gibt einen speziellen Eintrag, ..der auf das übergeordnete Verzeichnis verweist.

Das Ändern des Dateinamens ist also ganz einfach: Sie ändern nur den Namen im Verzeichniseintrag, sonst nichts. Dies gilt unabhängig davon, ob die Datei tatsächlich eine Datei ist oder eine "Datei", in der der Inhalt eines anderen Verzeichnisses gespeichert wird. In der Tat macht der gleiche renameSystemaufruf beides.

Das Kopieren ist jedoch weitaus weniger trivial. Sie konnte nur das Verzeichnis „Datei“, kopieren , aber dann würden Sie zwei Verzeichnisse haben , wo sind die Dateien identisch sind (sie harte Links sein würde). Wenn Sie ein System hätten, das Hardlinks zu Verzeichnissen zulässt, dann wäre dies das, aber da kein modernes System dies zumindest für Nicht-Root-Benutzer zulässt, müssen Sie diese Kopie für jedes Unterverzeichnis erstellen. Sie können tatsächlich cpnach diesem Verhalten fragen mit cp -lR: -lfür einen festen Link, -Rfür diese Rekursion.

Aber alles miteinander verbunden zu lassen, ist wahrscheinlich nicht das, was Sie wollen. Stattdessen möchten Sie cpjede Datei kopieren. Das ist ein ziemlich teurer Vorgang: Jede Datei muss in den Speicher eingelesen und an einer zweiten Stelle wieder auf die Festplatte geschrieben werden. Tatsächlich sind mehrere Systemaufrufe erforderlich, um die Dateien zu öffnen, zu lesen, zu schreiben und zu schließen. Dies muss für jede Datei wiederholt werden.

Herkömmliche Dateisysteme funktionieren auch auf der Festplatte auf diese Weise. Es gibt keine andere Möglichkeit, eine Reihe von Dateien zu kopieren, als jede Datei einzeln durchzugehen und zu kopieren. Dies sind die Dateisystemtypen, die bei der Entwicklung der grundlegenden Befehlszeilendienstprogramme verwendet wurden.


ist mving den gleichen „nur den Name im Verzeichniseintrag ändern“ von einem Dateisystem auf einen anderen?
RSLNX

5
Nein, dateisystemübergreifend ist dasselbe wie Kopieren + Löschen (tatsächlich renameschlägt der Syscall für dateisystemübergreifend fehl). Ich bin mir nicht sicher, ob in der Vergangenheit mvsogar Cross-Fs-Bewegungen unterstützt wurden.
Derobert

9
Ich kann Ihnen aus direkter Erfahrung und nicht aus Spekulationen sagen, dass die klassische mvTechnik keine geräteübergreifenden Bewegungen unterstützt. Früher wurde nur versucht rename(), eine Fehlermeldung auszudrucken, wenn dies fehlschlug. Ich erinnere mich noch an das schockierte Gefühl, als ich die neue Funktion zum ersten Mal aus Versehen verwendete. Warum dauert das so lange? Oh, es handelt sich um eine rekursive Kopie, die ich nicht beabsichtigt habe!
Alan Curry

5
@RuslanKhusnullin Befehlszeilenoptionen für allgemeine Befehle sind aufgrund ihrer Verwendung in Shell-Skripten sehr schwer zu ändern. Jemand kann vom aktuellen Verhalten von cp in Bezug auf das Ablehnen von Kopien abhängen. Das Cross-Fs-Zeug wurde wahrscheinlich als weniger bruchgefährdet eingestuft, obwohl es Alan, wie Sie sehen, immer noch überraschte.
Derobert

1
@derobert tat es nicht (dateisystemübergreifend mvfunktionierten nur einzelne Dateien unter BSD 4.2 unter VAX).
Vonbrand

21

Lassen Sie mich mit einer weiteren Frage beginnen:

Was ist der Unterschied zwischen cpund cp -R?

Nun, ohne das -RFlag ist es nur möglich, Dateien zu kopieren, da es eher ungewöhnlich ist, dass jemand ein Verzeichnis nicht rekursiv kopieren möchte: Eine nicht rekursive Kopie würde nur einen zweiten Namen für das Verzeichnis ergeben, der direkt auf dasselbe Verzeichnis verweist Struktur. Da dies nur selten gewünscht wird und es tatsächlich ein separates Programm gibt, das dies ausführt ( ln), ist eine nicht rekursive Kopie von Verzeichnissen nicht zulässig.

Was könnte dann der Unterschied zwischen mvund sein mv -R?

mv a bBenennt einfach einen einzelnen Eintrag im Verzeichnis um. Wenn also ein Verzeichnis mvbearbeitet wird, wird dessen Inhalt automatisch mit verschoben. In diesem Sinne mvliefert bereits die rekursive Eigenschaft, dh das "Umbenennen" aller Einträge im umbenannten Verzeichnis, zB von a/1bis b/1. Eine , mvdie nicht das tut, das heißt , die ein Verzeichnis umbenennt azu b, sondern hält a/1wie a/1, ist nicht das, was die Menschen verstehen , wenn sie sich beziehen , etwas zu bewegen: Wenn Sie einen Schrank bewegen, wird der Inhalt des Schrankes als auch bewegt. Diese andere Operation, bei der ein Verzeichnis ohne Inhalt verschoben wird, ist ebenfalls bereits verfügbar mkdir.


2
Das ist richtig, ich dachte nur an cpund mvals Operationen, die sie genannt werden: 'mache eine Kopie' und 'bewege dich'. Wenn ich also eine Tasse Kaffee kopieren möchte, würde ich mir eine weitere Tasse Kaffee mit der gleichen Füllung (Kaffeegetränk) wünschen. Das Problem ist, dass die Tools nicht für "normale Leute" gedacht sind, sondern für Nerds, die sich mit der Festplatten- und Dateisystemstruktur auskennen, und nicht für virtuelle Entitäten wie Dateien und Verzeichnisse.
RSLNX

1
Gut strukturierte, begründete Antwort.
Spedge

1
@RuslanKhusnullin Ihr Kaffee Analogie für arbeitet cpund mvauch - es erfordert keine Ebene von „nerdness“ zu verstehen, nur gesunden Menschenverstand. Eine echte Kopie einer Tasse Kaffee ist keine leere Tasse - Sie müssen nicht nur die Tasse, sondern auch den gesamten Inhalt (den Kaffee) rekursiv kopieren. Wenn Sie jedoch eine Tasse Kaffee bewegen, müssen Sie den Inhalt nicht separat bewegen - der Inhalt bewegt sich natürlich mit dem Behälter.
JW013

1
@ jw013 Du hast mich beeindruckt mit "Wenn du eine Tasse Kaffee umstellst, musst du den Inhalt nicht separat umstellen", es macht wirklich Sinn, danke. Aber es ist eine andere Abstraktionsebene. Ich denke, Sie meinen "eine Datei als Inode behandeln", während ich an Dateien denke, die Bytes ohne Metainformationen enthalten.
RSLNX

6

Normalerweise, wenn ich mit der Unix-Logik durcheinander bin, schaue ich mir Plan9 an, um zu sehen, wie Unix-Erfinder die gleichen Aufgaben Jahre später implementiert haben, ohne auf Abwärtskompatibilität zu verzichten.

So Plan9 Angebote cpund mvWerkzeuge mit Dateien arbeiten nur.

`cp f1 f2` creates f2 and copies f1's contents into it.
`mv f1 f2` renames f1 to f2 if f1 and f2 are in the same dir
           does `cp f1 f2 && rm f1` else
           can rename dirs (`mv d1 d2`) but will not move dir to another dir.

Zum Kopieren eines Verzeichnisses gibt es das dircpwirklich @{cd fromdir && tar c .} | @{cd todir && tar xT}(rc-Shell-Syntax)

Für das Verschieben einer Richtung gibt es meines Erachtens nur dircp d1 d2 && rm -r d1

Ich denke , diese Entscheidung zu begrenzen cpund mvfür Dateioperationen nur (nicht dirs) mehr Klarheit zu Plattenoperationen bringen und die Verwendung tarfür das Kopieren von Dateibäumen sind sehr komfortabel für das Verständnis und Scripting.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.