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?


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

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.


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.


@ 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.


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.


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.


1

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

  echo n | cp -vipr src/* dst
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.