Ich schlage vor, dass Sie rsync anstelle von cp verwenden, wenn Sie können, hat es die Option -m, die leere Ordner ausschließt, Beispiel:
rsync -am <origin> <destination>
Erklärung des Befehls in explainhell.com
Ich verwende die Option -a, weil sie viele nette Standardaktionen ausführt, aber wenn Sie möchten, können Sie auch die Option -r verwenden, die nur den rekursiven Modus einstellt.
[Kommentar hinzufügen]
Ich kenne keine Möglichkeit, dies mit cp zu tun, zumindest zeigt die Manpage keine Option, die das für Sie erledigt. Sie können wahrscheinlich eine komplexere Lösung finden, indem Sie den Befehl find
verwenden um eine Liste der zu kopierenden Dateien/Verzeichnisse zu finden und sie dann an cp zu übergeben, aber das wäre viel komplizierter als rsync. rsync ist sogar ziemlich Standard in vielen Linuxen
cp
hat zwar keine Option, nur Dateien zu erhalten, aber wie Berserck sagte, können Sie find
verwenden zusammen mit cp
. Tatsächlich ist dies wirklich einfach:
# Copy only files
find /path/to/file -type f -execdir cp "{}" /dest/path ";"
Oder:
# Copy everything except directories
find /path/to/file -not -type d -execdir cp "{}" /dest/path ";"
Erklärung
find
ist das Tool, das nach den gewünschten Dateien sucht. In der ersten Option setzen wir -type f
um nur reguläre Dateien zurückzugeben. In der zweiten Option setzen wir den -not -type d
um alles außer Verzeichnisse zu bekommen. find
führt die an -execdir
übergebenen Argumente aus ersetzt {}
mit jeweils einem Ergebniseintrag und stoppt den Befehl bei ;
gefunden wird (;
sollte \;
maskiert werden oder ";"
, oder die Shell könnte es erweitern).
-execdir
führt den Befehl mit dem Ordner der Datei als "Arbeitsverzeichnis" aus und ist besser als -exec
, siehe unten.
Die -type
Optionsdokumentation:
-Typ c
Datei ist vom Typ c:
b:block (buffered) special
c:Zeichen (ungepuffert) speziell
d:Verzeichnis
p:Named Pipe (FIFO)
f:normale Datei
l:symbolischer Link; dies ist nie wahr, wenn die Option -L oder die Option -follow aktiv ist, es sei denn, der symbolische Link ist unterbrochen. Wenn Sie nach symbolischen Links suchen möchten, wenn -L aktiv ist, verwenden Sie -xtype.
s:Steckdose
D:Tür (Solaris)
Die -not
Optionsdokumentation:
! Ausdruck
True, wenn expr falsch ist. Dieses Zeichen muss normalerweise auch vor der Interpretation durch die Shell geschützt werden.
-nicht expr
Gleich wie ! expr, aber nicht POSIX-kompatibel.
Die -execdir
Optionsdokumentation:
-exec Befehl;
Befehl; ausführen wahr, wenn der Status 0 zurückgegeben wird. Alle folgenden zu findenden Argumente werden als Argumente für den Befehl angesehen, bis ein Argument, das aus ';' angetroffen wird. Die Zeichenfolge '{}' wird überall dort, wo sie in den Argumenten des Befehls [...] vorkommt, durch den aktuellen Dateinamen ersetzt, der verarbeitet wird. Diese beiden Konstruktionen müssen möglicherweise maskiert (mit einem '\') oder in Anführungszeichen gesetzt werden, um sie vor einer Erweiterung durch die Shell zu schützen. Der angegebene Befehl wird einmal für jede übereinstimmende Datei ausgeführt. Der Befehl wird im Startverzeichnis ausgeführt. Es gibt unvermeidliche Sicherheitsprobleme im Zusammenhang mit der Verwendung der Aktion -exec; Sie sollten stattdessen die Option -execdir verwenden.
-execdir Befehl;
Wie -exec, aber der angegebene Befehl wird aus dem Unterverzeichnis ausgeführt, das die übereinstimmende Datei enthält , was normalerweise nicht das Verzeichnis ist, in dem Sie find gestartet haben. Dies ist eine viel sicherere Methode zum Aufrufen von Befehlen, da es Racebedingungen während der Auflösung der Pfade zu den übereinstimmenden Dateien vermeidet. [...] Wenn Sie diese Option verwenden, müssen Sie sicherstellen, dass Ihre $PATH-Umgebungsvariable nicht auf '.' verweist; Andernfalls kann ein Angreifer beliebige Befehle ausführen, indem er eine entsprechend benannte Datei in einem Verzeichnis hinterlässt, in dem Sie -execdir ausführen. Gleiches gilt für Einträge in $PATH, die leer oder keine absoluten Verzeichnisnamen sind.
https://linux.die.net/man/1/find