Obwohl diese Frage und ihre akzeptierte Antwort uralt sind, füge ich meine Antwort hinzu, da die derzeit vorhandenen Fragen cp
entweder einige Randfälle nicht behandeln oder interaktiv arbeiten müssen. Oft spielen Edge-Cases / Skriptfähigkeit / Portabilität / mehrere Quellen keine Rolle. In diesem Fall gewinnt die Einfachheit, und es ist besser, cp
direkt mit weniger Flags (wie in anderen Antworten) zu verwenden, um die kognitive Belastung zu verringern - aber für diese anderen Zeiten (oder für eine robust wiederverwendbare Funktion) Dieser Aufruf / diese Funktion ist nützlich und übrigens nicht bash-spezifisch (mir ist klar, dass es sich bei dieser Frage um Bash handelt, also ist das in diesem Fall nur ein Bonus). Einige Flags können abgekürzt werden (zB mit-a
), aber ich habe alle explizit in Langform aufgenommen (außer-R
siehe unten) zur Erläuterung. Entfernen Sie einfach alle Flags, wenn es eine Funktion gibt, die Sie speziell nicht möchten (oder wenn Sie ein Nicht-Posix-Betriebssystem verwenden oder Ihre Version cp
dieses Flags nicht verarbeitet - ich habe dies auf GNU Coreutils 8.25 getestet cp
):
mergedirs() {
_retval=0
_dest="$1"
shift
yes | \
for _src do
cp -R --no-dereference --preserve=all --force --one-file-system \
--no-target-directory "${_src}/" "$_dest" || { _retval=1; break; }
done 2>/dev/null
return $_retval
}
mergedirs destination source-1 [source-2 source-3 ...]
Erläuterung:
-R
: hat eine subtil andere Semantik als -r
/ --recursive
auf einigen Systemen (insbesondere in Bezug auf spezielle Dateien in Quellverzeichnissen), wie in dieser Antwort erläutert
--no-dereference
: Folgen Sie niemals symbolischen Links in SOURCE
--preserve=all
: Behalten Sie die angegebenen Attribute bei (Standard: Modus, Besitz, Zeitstempel), wenn möglich zusätzliche Attribute: Kontext, Links, xattr, alle
--force
: Wenn eine vorhandene Zieldatei nicht geöffnet werden kann, entfernen Sie sie und versuchen Sie es erneut
--one-file-system
: Bleiben Sie in diesem Dateisystem
--no-target-directory
: Treat DEST als normale Datei (erklärt in in dieser Antwort , nämlich: If you do a recursive copy and the source is a directory, then cp -T copies the content of the source into the destination, rather than copying the source itself.
)
- [piped input from
yes
]: Auch wenn --force
in diesem speziellen rekursiven Modus cp
noch gefragt wird, bevor jede Datei überlastet wird, erreichen wir eine Nicht-Interaktivität, indem wir die Ausgabe von dort yes
an sie weiterleiten
- [Ausgabe an
/dev/null
] weitergeleitet: Dies dient dazu, die unordentliche Reihe von Fragen nach dem Vorbild von zum Schweigen zu bringencp: overwrite 'xx'?
- [return-val & Early Exit]: Dies stellt sicher, dass die Schleife beendet wird, sobald eine Kopie fehlgeschlagen ist, und kehrt zurück,
1
wenn ein Fehler aufgetreten ist
Übrigens:
- Ein funky neues Flag, das ich auch auf meinem System verwende, ist das
--reflink=auto
Erstellen sogenannter "Light Copies" (Copy-on-Write) mit den gleichen Geschwindigkeitsvorteilen wie beim Hardlink und den gleichen Größenvorteilen bis und in umgekehrtem Verhältnis um wie viel die Dateien in der Zukunft divergieren). Dieses Flag wird in der letzten GNU akzeptiert cp
und ist mehr als ein No-Op mit kompatiblen Dateisystemen auf neueren Linux-Kerneln. YMWV-viel auf anderen Systemen.
cp -r html_new/* html
? Sie können dashtml_new
Verzeichnis anschließend entfernen .