Linux wie kopieren, aber nicht überschreiben?

385

Ich möchte cpein Verzeichnis erstellen, aber ich möchte keine vorhandenen Dateien überschreiben, auch wenn diese älter als die kopierten Dateien sind. Und ich möchte es völlig nicht interaktiv machen, da dies Teil eines Crontab Bash-Skripts sein wird. Irgendwelche Ideen?

mnowotka
quelle

Antworten:

589

Entnommen aus der Manpage :

-n, --no-clobber
              do not overwrite an existing file (overrides a previous -i option)

Beispiel:

cp -n myoldfile.txt mycopiedfile.txt
hovanessyan
quelle
32
Beachten Sie, dass dies mit einem Fehler beendet wird, wenn die Datei vorhanden ist. Um mit Erfolg zu cp -n source.txt destination.txt || true
beenden
13
@galenandrew cp -nwird nicht mit Fehler beendet, wenn die Datei unter Ubuntu 12.04 vorhanden ist.
Amit
@galenandrew Bestätigt. Vielen Dank. Mein Projekt wurde nicht in Xcode erstellt, nachdem ich meinem Ziel ein Ausführungsskript hinzugefügt hatte.
Ruiz
@ AaronFranke sieht so aus.
Boris
93

Erwägen Sie die Verwendung rsync.

rsync -a -v --ignore-existing src dst

Laut Kommentar rsync -a -v src dstist dies nicht korrekt, da vorhandene Dateien aktualisiert werden.

Hans Ginzel
quelle
7
Sie möchten das --ignore-existingFlag hinzufügen , um zu verhindern, dass vorhandene Dateien überschrieben werden.
Alle Arbeiter sind essentiell
7
Vollständiger Befehl rsync -a -v --ignore-existing <src> <dst>ist in der Tat die richtige Antwort, anstatt cp -uoben.
Whitebird
Wenn eine vorherige Kopie unterbrochen und nur eine abgeschnittene Datei kopiert wurde, wird cp -u sie sicher nicht erneut kopieren ... aber wird rsync mit --ignore-existent? Wahrscheinlich auch nicht ... das macht sie perfekt gleichwertig, oder?
Dagelf
rsync behält den Datei-Zeitstempel bei, während cp die aktuelle Zeit verwendet (meiner Erfahrung nach)
Stefan Diabo
1
Einige Server haben einfach keine Rsync
Mebada
51
cp -n

Ist was du willst. Siehe die Manpage.

Bucko
quelle
@ AaronFranke ja, es wird rekursiv funktionieren.
Boris
33

Dies funktioniert auf RedHat:

false | cp -i source destination 2>/dev/null

Aktualisieren und nicht überschreiben ist etwas anderes.

ceving
quelle
4
Was macht falsehier?
Frozen Flame
11
@FrozenFlame Beantwortet -iFragen.
Ceving
Offensichtlich funktioniert dieser Befehl nicht, wenn Sie versuchen, mehr als ARG_MAX-Dateien zu kopieren. Überprüfen Sie diesen Link, um diesen Fall zu umgehen .
Mginius
2
Natürlich funktioniert dieser Befehl auch nicht, wenn die Erde in die Sonne kracht.
27.
32

Für Leute, die feststellen, dass sie keine 'n'-Option haben (wie ich bei RedHat), können Sie cp -udie Datei nur schreiben, wenn die Quelle neuer als die vorhandene ist (oder wenn keine vorhanden ist).

[Bearbeiten] Wie in den Kommentaren erwähnt, werden dadurch ältere Dateien überschrieben, was nicht genau das ist, was das OP wollte. Verwenden Sie dafür die Antwort von Ceving.

Grimmig...
quelle
11
OP hat darum gebeten, vorhandene Dateien nicht zu überschreiben, auch wenn sie älter als kopierte Dateien sind -u.
Andrew Lott
4
Meine Güte, du hast absolut recht. Ich bin überrascht, dass es so lange gedauert hat, bis es jemand bemerkt hat.
Grimmig ...
Es ist vielleicht nicht das, wonach das OP gefragt hat, aber es ist genau das, was ich für meinen Uberspace (Centos 7) brauchte. Vielen Dank!
Thomas Praxl
Ich bin froh, dass ich vor sechs Jahren helfen konnte :-D
Grim ...
10

Alpine Linux: Die folgende Antwort gilt nur für den Fall einer einzelnen Datei: In Alpine cp -nfunktioniert es nicht (und false | cp -i ...auch nicht). In meinem Fall funktioniert also eine Lösung, die ich gefunden habe:

if [ ! -f env.js ]; then cp env.example.js env.js; fi 

Wenn im obigen Beispiel env.jskeine Datei vorhanden ist, kopieren wir env.example.jsin env.js.

Kamil Kiełczewski
quelle
1

Einige Versionen von cp verfügen nicht über die Option --no-clobber . In diesem Fall:

  echo n | cp -vipr src/* dst
Octavian
quelle