Linux comment copier mais pas écraser?

386

Je veux cpun répertoire mais je ne veux pas écraser les fichiers existants même s'ils sont plus anciens que les fichiers copiés. Et je veux le faire complètement non interactif car cela fera partie d'un script Crontab Bash. Des idées?

mnowotka
la source

Réponses:

589

Tiré de la page de manuel :

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

Exemple:

cp -n myoldfile.txt mycopiedfile.txt
hovanessyan
la source
33
Notez que cela se terminera avec une erreur si le fichier existe. Pour sortir avec succès, essayez cp -n source.txt destination.txt || true
galenandrew
13
@galenandrew cp -nne se ferme pas avec une erreur si le fichier existe sur Ubuntu 12.04.
Amit
@galenandrew Confirmé. Je vous remercie. Mon projet n'était pas en cours de construction dans Xcode après avoir ajouté un script d'exécution à ma cible.
Ruiz
@AaronFranke ressemble à ça.
Boris
93

Pensez à utiliser rsync.

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

Selon les commentaires rsync -a -v src dstn'est pas correct car il mettra à jour les fichiers existants.

Hans Ginzel
la source
7
Vous souhaitez ajouter l' --ignore-existingindicateur pour empêcher l'écrasement des fichiers existants.
Tous les travailleurs sont essentiels
7
La commande complète rsync -a -v --ignore-existing <src> <dst>est en effet la bonne réponse, au lieu de cp -uci - dessus.
Whitebird
Si une copie précédente a été interrompue et que seul un fichier tronqué a été copié, je suis sûr que cp -u ne la recopiera pas ... mais rsync, avec --ignore-existing? Probablement pas non plus ... ce qui les rend parfaitement équivalents, non?
dagelf
rsync conserve l'horodatage du fichier tandis que cp utilise l'heure actuelle (d'après mon expérience)
Stefan Diabo
1
certains serveurs n'ont tout simplement pas de rsync
mebada
51
cp -n

C'est ce que tu veux. Voir la page de manuel.

bucko
la source
@AaronFranke oui, cela fonctionnera récursivement.
Boris
33

Cela fonctionnera sur RedHat:

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

La mise à jour et non l'écrasement est quelque chose de différent.

ceving
la source
4
Que fait false-on ici?
Frozen Flame
11
@FrozenFlame Répond aux -iquestions.
ceving
De toute évidence, cette commande ne fonctionnera pas si vous essayez de copier plus de fichiers ARG_MAX. Pour contourner ce cas, consultez ce lien .
mginius
2
De toute évidence, cette commande ne fonctionnera pas si la terre s'écrase au soleil.
ceving
32

Pour les personnes qui n'ont pas d'option 'n' (comme moi sur RedHat), vous pouvez utiliser cp -upour écrire le fichier uniquement si la source est plus récente que celle existante (ou s'il n'y en a pas déjà une).

[modifier] Comme mentionné dans les commentaires, cela écrasera les fichiers plus anciens, ce n'est donc pas exactement ce que l'OP voulait. Utilisez la réponse de Ceving pour cela.

Sinistre...
la source
11
OP a demandé de ne pas écraser les fichiers existants même s'ils sont plus anciens que les fichiers copiés , donc -une correspond pas vraiment à l'objectif.
Andrew Lott
4
Dieu, vous avez absolument raison. Je suis surpris qu'il ait fallu si longtemps à quiconque pour le remarquer.
Grim ...
Ce n'est peut-être pas ce que l'OP a demandé, mais c'est exactement ce dont j'avais besoin pour mon Uberspace (Centos 7). Merci!
Thomas Praxl
Je suis content qu'il y a six ans, j'ai pu aider :-D
Grim ...
10

Alpine linux: La réponse ci - dessous est uniquement pour le cas d'un seul fichier: en alpin cp -nne fonctionne pas (et false | cp -i ...aussi) donc la solution qui fonctionne dans mon cas que j'ai trouvée est:

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

Dans l'exemple ci-dessus, si le env.jsfichier n'existe pas, nous copions env.example.jsvers env.js.

Kamil Kiełczewski
la source
1

Certaines versions de cp n'ont pas l' option --no-clobber . Dans ce cas:

  echo n | cp -vipr src/* dst
Octavian
la source