Unterschied Kopieren des Inhaltsordners zwischen /. und / * unter Linux

8

Um Inhalte aus einem Ordner zu kopieren, den ich gelesen habe, verwenden Sie:

cp -rfva ../foldersource/. ./

aber das funktioniert auch

cp -rfva ../foldersource/* ./

Gibt es einen Unterschied?

Zum Beispiel, wenn ich einen Inhalt aus einem Ordner mit löschen möchte. ::

rm -rf ../foldersource/.

Ich bekomme den Fehler:

rm:  rejet delete folder '.' or '..':

aber mit Sternchen ist ok

rm -rf ../foldersource/*

Sternchen ist also eine bessere Option, die überall funktioniert?

Stackdave
quelle

Antworten:

10

Es gibt einen grundlegenden Unterschied zwischen diesen beiden Argumentationsformen. Und es ist wichtig zu verstehen, was passiert.

Mit ../foldersource/.dem Argument wird unverändert an den Befehl übergeben, ob es cpoder rmoder etwas anderes ist. Es ist Sache des Befehls, ob dieser nachfolgende Punkt eine spezielle oder eindeutige Semantik aufweist, die sich von der Standard-Unix-Konvention unterscheidet, einfach auf das Verzeichnis zu verweisen, in dem er sich befindet. beides rmund cpscheinen es als Sonderfall zu behandeln.

Mit ../foldersource/*dem Argument zuerst von der Shell erweitert wird , bevor der Befehl immer wird auch ausgeführt und Argumente übergeben. So rmsieht nie ../foldersource/*; es sieht die erweiterte Version ../foldersource/file1.ext ../foldersource/file2.ext ../foldersource/childfolder1und so weiter. Dies ist wichtig, da Betriebssysteme die Anzahl der Argumente begrenzen, die an einen Befehl übergeben werden können, normalerweise nur einige Hundert.

Eestrada
quelle
4
It's up to the command whether that trailing dot makes any senseÄhm, der Punkt ist immer mit dem enthaltenen Verzeichnis selbst verknüpft, ../foldersource/.sollte sich also nicht von der Angabe unterscheiden ./foldersource/und ist in der Tat nur eine redundante Möglichkeit, dasselbe anzugeben. Kein Befehl versucht, einen Punkt oder einen Doppelpunkt zu "verstehen", da diese unter Linux / Unix-Dateisystemen Standard sind. rmlehnt es einfach ab, das aktuelle Arbeitsverzeichnis zu entfernen, wie jimmijin der Antwort angegeben. Beachten Sie außerdem, dass Sie ./in all Ihren Beispielen OP verwenden ../. Ein etwas großer Unterschied.
Sergiy Kolodyazhnyy
"cp -rfva ../foldersource/. ./" entspricht "cp -rfva ../foldersource ./". Ich möchte den Inhalt der Ordnerquelle kopieren, aber nicht den Ordner root
stackdave
1
@Stackdave nein, cp -rfva ../foldersource/. ./ ist NICHT gleichbedeutend mit cp -rfva ../foldersource ./ . Das Nachlaufen /.ist signifikant
Roaima
2
Während das, was diese Antwort sagt, richtig ist, fehlt ein sehr wichtiger Unterschied, wie in der Antwort von @ roaima erwähnt: Die / * -Variante kopiert (normalerweise) keine Dateien oder Verzeichnisse, die mit beginnen.
Adam
@SergiyKolodyazhnyy Du hast recht; Dies .ist eine Standardkonvention in Unix, um den Strom direkt zu bezeichnen. Vielen Dank auch für den Hinweis, dass ich ./in meinen Beispielen verwendet habe, wann ich hätte verwenden sollen ../; Ich werde das beheben. Sie sind sich nicht sicher, ob Befehle für den nachfolgenden Punkt "sinnvoll" sind. wie das OP cpbeide hervorhebt (und mit beiden erlebt habe ) rmund cpsich anders verhalten, wenn ein Trailing .vorhanden ist. Ich hätte etwas schreiben sollen wie "Es liegt am Befehl, ob der nachfolgende Punkt eine spezielle oder eindeutige Semantik hat". Ich werde meine Antwort aus Gründen der Klarheit ändern.
Eestrada
10

Wenn Sie mit kopieren, kopieren cp -a source/* target/Sie die meisten Dateien und Verzeichnisse von sourcenach target. Insbesondere handelt es sich bei den ausgeschlossenen Elementen wahrscheinlich um Dateien, die mit einem Punkt ( .) in der obersten Ebene von beginnen source.

Betrachten Sie diese Dateien (oder Verzeichnisse) in source

apple        # will be copied
banana/      # will be copied, as will all its contents
.cherry      # will not be copied

Wenn Sie mit kopieren, cp -a source/. target/kopieren Sie den gesamten Inhalt von source, einschließlich aller Elemente, die mit einem Punkt ( .) beginnen, nachtarget

Betrachten Sie diese Dateien (oder Verzeichnisse) in source

apple        # will be copied
banana/      # will be copied, as will all its contents
.cherry      # will be copied

Wenn Sie verwenden bash, zshkönnen Sie die verwenden dotglobOption , die Bedeutung zu ändern , *so dass sie beginnen , Dateien und Verzeichnisse mit einem Punkt enthält ( yashhat auch eine dotglobOption, aber es schließt dann .und ... In glob Erweiterungen , die ihre Verwendbarkeit einschränkt Siehe auch FIGNORE='@(.|..)'in ksh93).

Interessanterweise cp -a source/. target/wird garantiert nie die Komponente erstellt target/source. (Auf der anderen Seite cp -a source target/wird eines von zwei Dingen ausgeführt, je nachdem, ob es targetbereits vorhanden ist oder nicht . Weitere Informationen finden Sie unter Kopieren eines Ordners auf idempotente Weise mit cp .)


Wenn Sie mit löschen, löschen rm -rf source/*Sie die Dateien und Verzeichnisse source, die nicht mit einem Punkt ( .) beginnen. Vorbehaltlich der dotglobbereits erwähnten Einstellung. Das Verzeichnis sourceselbst wird nicht gelöscht .

Wenn Sie versuchen, mit zu löschen, schlägt rm -rf source/.dies fehl - wie andere bereits erklärt haben -, da POSIX das Löschen eines Pfads verbietet, dessen letzte Komponente .oder ist ... Das nächste Äquivalent ist rm -rf source, das das sourceVerzeichnis und seinen gesamten Inhalt löscht, unabhängig davon, ob sie mit einem Punkt ( .) beginnen oder nicht .

Roaima
quelle
1
Siehe auch Löscht 'rm. *' Das übergeordnete Verzeichnis jemals? über das rm -rf .Scheitern .
Stéphane Chazelas
7

Sie können dies nicht tun, rm -rf ../foldersource/.da rmdies nicht zulässig ist, wie im Handbuch ausdrücklich angegeben:

Jeder Versuch, eine Datei zu entfernen, deren letzte Dateinamenkomponente '.' oder '..' wird ohne Aufforderung abgelehnt, wie von POSIX vorgeschrieben.

und im POSIX-Handbuch sehen man 1p rmwir:

Wenn eine der Dateien Punkt oder Punkt-Punkt als Basisnamen-Teil eines Operanden (dh der endgültigen Pfadnamen-Komponente) angegeben ist oder wenn ein Operand in das Stammverzeichnis aufgelöst wird, schreibt rm eine Diagnosemeldung in den Standardfehler und unternimmt nichts mehr mit solchen Operanden.

jimmij
quelle