Meine Frage ist, warum es erforderlich ist, das -r
(rekursive) Flag zu verwenden, wenn Sie eine Kopie eines Verzeichnisses erstellen? Das heißt, warum dies tun:
$ cp -r dir1 copyDir1
Wann möchte ich dieses Verhalten beim Kopieren eines Verzeichnisses nicht?
Ist eine rekursive Kopie eines Verzeichnisses nicht wirklich das „Standardverhalten“? das Verhalten, das wir fast die ganze Zeit wollen?
Es fühlt sich so an, als wäre dies eine überflüssige Flagge.
rm
Antworten:
So wie Dateisysteme funktionieren, ist ein Verzeichnis eigentlich kein Ordner, der Dateien enthält, sondern ein Verzeichnis ist eine Datei, die Inode-Zeiger auf „untergeordnete“ Dateien enthält, die mit ihm verbunden sind. Aus Sicht des Dateisystems ist eine Datei eine Datei, ein Verzeichnis jedoch nur eine Datei mit einer Liste der verbundenen Dateien.
Also aus der Kommandozeilenperspektive:
Würde im Grunde bedeuten, die genannte Datei
dir1
in eine neue Datei mit dem Namen zu kopierencopyDir1
. Und was das Dateisystem betrifft,dir1
ist es sowieso nur eine Datei; Die Tatsache, dass es sich um ein „Verzeichnis“ handelt, wird nur sichtbar, wenn das Dateisystem tatsächlich prüftdir1
, um festzustellen, was dieser Stapel von Bits tatsächlich ist.Das
-r
Flag weist das Dateisystem an, den Datei- / Verzeichnisbaum rekursiv zu rollen und alle Inhalte, die ein „Kind“ dieser Datei sein könnten, an einen neuen Ort zu kopieren.Nun, warum das überflüssig oder überflüssig erscheint, hängt es wirklich mit historischen Methoden des Umgangs mit Dateisystemen zusammen. Sowie die Schaffung eines Systems, das vor allen Arten von benutzerbezogenen Fehlern sicher ist; zufällig sowie absichtlich.
Das heißt, sagen wir , Sie eine haben
~/bin
Datei in Ihrem Home - Verzeichnis , das Sie kopieren möchten , aber die versehentlich ausgelassen~
-weil Sie ein Mensch und machen Fehler-so sein gerade sind/bin
wie folgt aus :Mit dem „Sicherheitsnetz“
/bin
, ein Verzeichnis zu sein, verbunden mit der Notwendigkeit des-r
Flags, vermeiden Sie, dass Sie versehentlich die gesamte Binärwurzel des Systems, auf dem Sie sich befinden, in Ihr Home-Verzeichnis kopieren. Wenn dieses Sicherheitsnetz nicht vorhanden wäre, würde eine kleine - oder möglicherweise große - Katastrophe eintreten.Die Logik hier ist, dass in den Tagen vor der GUI (grafische Benutzeroberflächen) logische / Verhaltens-Konventionen festgelegt werden müssen, um zu vermeiden, dass der Benutzer Pannen verursacht, die ein System möglicherweise töten können. Und die
-r
Flagge zu benutzen ist jetzt eine davon.Wenn das überflüssig erscheint, brauchen Sie nicht weiter zu suchen als mit einem modernen GUI-System, das man über Linux-Dateisystemen platzieren kann. Eine grafische Benutzeroberfläche behebt grundlegende Benutzerprobleme wie diese, indem sie das einfache Ziehen und Ablegen von Dateien und Verzeichnissen ermöglicht.
Aber im Bereich der textbasierten Benutzeroberflächen ist ein Großteil der „Benutzererfahrung“ in dieser Welt im Grunde genommen nur logische und hueristische Unebenheiten, die dazu beitragen, den Benutzer in Schach zu halten, damit potenzielle Katastrophen abgewendet werden können.
Auf ähnliche Weise haben Linux / Unix-Dateisysteme standardmäßig keine
777
Berechtigungen undsudo
Rechte festgelegt und wie echte Systemadministratoren zusammenzucken, wenn ein Benutzer777
Berechtigungen festlegt oder jedemsudo
Rechte gewährt . Dies sind die grundlegenden Dinge, die man tut, um sicherzustellen, dass das System stabil und so benutzerfreundlich wie möglich ist. Wer sich beeilt, diese Konventionen kurzzuschließen, wird höchstwahrscheinlich sein System beschädigen, ohne es überhaupt zu wissen.ZUSÄTZLICHE INFORMATIONEN: Eine andere Antwort hier auf der Unix Stack Exchange-Website gibt eine gute Erklärung dafür, warum eine nicht rekursive Kopie eines Verzeichnisses problematisch ist. Betonung liegt bei mir.
Wenn ein Verzeichnis also nur eine Datei mit Inode-Elementen ist, entspricht das Erstellen einer direkten Kopie dieser Datei der Funktionsweise einer festen Verknüpfung. Welches ist nicht das, was jemand will.
quelle
cp -r /bin
wiecp-r ~/bin
. Die Flagge selbst verhindert nicht, dass Fehler gemacht werden oder dass jemand besser aufpasst. Wenn Sie Fehler vermeiden möchten, kann der Befehl cp den betreffenden Knoten genauso einfach anzeigen und eine Eingabeaufforderung wie "Dies ist ein Verzeichnis, möchten Sie den gesamten Inhalt an den angegebenen Speicherort kopieren (y / n)? Das wäre ein Sicherheitsnetz . Durch das Erfordernis von -r für Verzeichnisse bleibt der Code mehr als alles andere aufgebläht.Es ist sehr richtig, dass wir dieses Verhalten fast die ganze Zeit wollen. Dies bedeutet jedoch nicht unbedingt, dass das rekursive Kopieren das Standardverhalten sein sollte.
Ich denke, die Gründe
cp
dafür liegen in der Unix-Philosophie . Unix bevorzugt Programme, die eine Sache tun und es gut machen , sowie Programme, die sowohl in der Oberfläche als auch in der Implementierung einfach sind (manchmal als schlechter ist besser bezeichnet ).Das Schlüsselstück des Puzzles ist die Erkenntnis, dass
cp
keine Verzeichnissecp
kopiert werden - es werden Dateien (und nur Dateien) kopiert . Wenn Sie ein Verzeichnis kopieren möchten,cp
rufen Sie sich rekursiv auf , um die Dateien in jedes Verzeichnis zu kopieren.Natürlich ist der Unterschied zwischen dem "Kopieren von Verzeichnissen" und dem "rekursiven Kopieren von Dateien" aus Benutzersicht absolut nichts, aber diese Schnittstelle hilft bei der Implementierung, einfach zu bleiben .
Wenn Sie
cp
Verzeichnisse kopieren könnten, wären Sie bald versucht, weitere Funktionen hinzuzufügen, die nur für Verzeichnisse sinnvoll sind. Sie möchten beispielsweise möglicherweise nur Dateinamen kopieren, die auf enden.sh
. Dies führt unweigerlich zu dem Aufblähen und Funktionsschleichen , das wir von anderen Betriebssystemen gewohnt sind - was Software langsam, komplex und fehleranfällig macht.Ein weiterer Vorteil ist, dass
-r
der Benutzer auch besser verstehen kann, was unter der Benutzeroberfläche wirklich passiert. Ein netter Nebeneffekt davon ist, dass das Erlernen des Konzepts der rekursiven Operation Ihnen einige Arbeit erspart, wenn Sie mehr über andere Tools erfahren, die dies unterstützen (wiegrep
zum Beispiel).Einige Leute werden Sie sicher sagen , dass Implementierungsdetails für den Benutzer auszusetzen ist schlecht , und dass mehr Funktionen aufweist , ist gut . Meine Absicht hier ist nur, die Gründe für dieses Verhalten zu erklären, also werde ich nicht versuchen, so oder so zu argumentieren.
quelle
Durch die Interaktion mit Verzeichnissen wird sichergestellt, dass Sie mit einem Verzeichnis und NICHT nur mit einer einzelnen Datei interagieren.
Zum Beispiel:
Wenn Sie also einen Ordner erfolgreich kopieren möchten, müssen Sie ihn so behandeln, als wäre er eine Sammlung von Dateien:
quelle
Das Ändern der Standardeinstellung hätte zur Folge, dass Tausende von Shell-Skripten nicht mehr funktionieren. Dies führt zu den POSIX- und SUS-Anforderungen für das bekannte Standardverhalten.
Der Grund ist die historische Entwicklung der Befehle cp, ln und mv (auf den meisten alten UNIX-Systemen alle gleich binär) in verschiedenen UNIX-Zweigen. Als es
-r
erschien (Earlycp
hatte keine Möglichkeit, Verzeichnisse zu kopieren; hier ist eine frühe Manpage ohne-r
oder-R
), gab es verschiedene Unterschiede im Umgang mit speziellen Dateien, Symlinks und anderen Unklarheiten des Dateisystems.Aus den Open Group Base-Spezifikationen, Ausgabe 7 :
Tatsächlich werden Sie immer noch einige Leute sehen, die regelmäßig Folgendes verwenden:
Weil sie nicht darauf vertrauen, dass die
cp -r
Implementierung so ist, wie sie es von einer beliebigen Maschine gewohnt ist. Oder weil sie dastar
Verhalten wollen .quelle
Es mag heute eine suboptimale Benutzeroberfläche sein, aber es war eine Entscheidung, die irgendwann um 1970 während des Entwurfs von UNIX getroffen wurde, als die Festplatte erheblich teurer war. Millionen von Shell-Skripten hängen davon ab, dass sie auf diese Weise funktionieren, und es ist viel zu spät, um sie zu ändern.
In diesem Artikel finden Sie Informationen zum Originaldesign.
quelle
Ein klarer Vorteil des
-r
Flags ist, dass Siecp * /target/dir
nur alle Dateien im Quellverzeichnis in das Zielverzeichnis kopieren können , wobei (wenn auch mit einer Warnung) alle darin enthaltenen Verzeichnisse weggelassen werden.cp -r * /target/dir
würde stattdessen alles kopieren, einschließlich der Unterverzeichnisse.quelle
Sie benötigen dieses Flag nur, wenn
cp
es sich um einen Befehl zum Kopieren von Dateien und Verzeichnissen handelt und nicht nur von Verzeichnissen.Wenn es einen speziellen Befehl für das Kopieren von Verzeichnissen gäbe, wäre das "Standard" -Verhalten sicherlich eine rekursive Kopie.
quelle
mkdir
?Wie bereits erwähnt, handelt es sich bei einem Verzeichnis im Grunde genommen nur um einen anderen Dateityp (im Gegensatz zu einer regulären Datei), der normalerweise andere Dateien "enthält" (auf diese verweist). Es kann Unterverzeichnisse enthalten, für die das Gleiche gilt ...
Wenn Sie also ein Verzeichnis kopieren (Benutzerperspektive), kopieren Sie tatsächlich eine Reihe von Dateien (Dateisystemperspektive) (reguläre Dateien, Verzeichnisdateien, symbolische Links, ...) und wiederholen dies für jede Verzeichnisdatei rekursiv Prozess. Da das Kopieren eines Verzeichnisses per Definition ein rekursiver Prozess ist, wird das Argument von cp aufgerufen
--recursive
.Es ist natürlich sehr einfach, eine Befehlsverknüpfung in Ihrer Benutzerumgebung zu erstellen (fügen Sie diese in Ihre .profile / .bashrc-Datei ein, um sie dauerhaft verfügbar zu machen):
Oder vielleicht besser:
Auf diese Weise können Sie ein Verzeichnis mit kopieren
cpa dir1 copyDir1
und es wird nicht nur gedruckt, was kopiert wird, sondern auch Dateiberechtigungen angewendet.Und da jemand erwähnt hat, dass cp theoretisch erkennen könnte, dass die Quelldatei ein Verzeichnis ist, und fragt, ob sie rekursiv kopiert werden soll, hier ein kurzer Vorschlag:
Dies ist nur ein billiger CP-Wrapper. Es werden immer alle Metadaten beibehalten (dh die Änderungszeit der Datei wird kopiert, die Symlinks werden ordnungsgemäß kopiert usw.). Wenn Sie versuchen, ein Verzeichnis zu kopieren, werden Sie gefragt, ob es (rekursiv) kopiert werden soll.
quelle