Linux como copiar, mas não substituir?

386

Quero cpum diretório, mas não quero substituir nenhum arquivo existente, mesmo que seja mais antigo que os arquivos copiados. E quero fazê-lo completamente não interativo, pois isso fará parte de um script do Crontab Bash. Alguma ideia?

mnowotka
fonte

Respostas:

589

Retirado da página de manual :

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

Exemplo:

cp -n myoldfile.txt mycopiedfile.txt
hovanessyan
fonte
33
Observe que isso será encerrado com um erro se o arquivo existir. Para sair com sucesso, tente cp -n source.txt destination.txt || true
galenandrew
13
@galenandrew cp -nnão sai com erro se o arquivo existir no Ubuntu 12.04.
amit
@galenandrew Confirmado. Obrigado. Meu projeto não estava sendo construído no Xcode depois de adicionar um script de execução ao meu destino.
Ruiz
@AaronFranke parece que sim.
Boris
93

Considere usar rsync.

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

Conforme comentários rsync -a -v src dstnão está correto, porque ele atualizará os arquivos existentes.

Hans Ginzel
fonte
7
Você deseja adicionar o --ignore-existingsinalizador para impedir que os arquivos existentes sejam substituídos.
Todos os trabalhadores têm Essencial
7
Comando completo rsync -a -v --ignore-existing <src> <dst>é realmente a resposta correta, em vez de cp -uacima.
Whitebird
Se uma cópia anterior foi interrompida e apenas um arquivo truncado foi copiado, tenho certeza que o cp -u não a copiará novamente ... mas será rsync, com --ignore-existente? Provavelmente também não ... então isso os torna perfeitamente equivalentes, certo?
dagelf
rsync mantém o timestamp arquivo enquanto cp usa a hora atual (na minha experiência)
Stefan Diabo
11
alguns servidores apenas não tem rsync
mebada
51
cp -n

É o que você quer. Veja a página do manual.

bucko
fonte
@AaronFranke sim, funcionará recursivamente.
Boris
33

Isso funcionará no RedHat:

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

Atualizar e não substituir é algo diferente.

ceving
fonte
4
O que falsefaz aqui?
Frozen Flame
11
@FrozenFlame Responde a -iperguntas.
ceving
Obviamente, esse comando não funcionará se você tentar copiar mais do que arquivos ARG_MAX. Para contornar esse caso, verifique este link .
mginius
2
Obviamente, esse comando não funcionará se a Terra colidir com o sol.
ceving 27/01
32

Para pessoas que acham que não tem uma opção 'n' (como eu no RedHat), você pode usar cp -upara escrever o arquivo apenas se a fonte for mais nova que a existente (ou se não houver).

[editar] Como mencionado nos comentários, isso substituirá os arquivos mais antigos, portanto não é exatamente o que o OP queria. Use a resposta de ceving para isso.

Grim ...
fonte
11
O OP pediu para não sobrescrever os arquivos existentes, mesmo que sejam mais antigos que os arquivos copiados , portanto -u, na verdade, não se encaixa.
Andrew Lott
4
Deus, você está absolutamente certo. Estou surpreso que demorou tanto para alguém perceber.
Grim ...
Pode não ser o que o OP pediu, mas é exatamente o que eu precisava para o meu Uberspace (Centos 7). Obrigado!
Thomas Praxl
Estou feliz há seis anos que eu poderia ajudar :-D
Grim ...
10

Alpine linux: A resposta abaixo é apenas para o caso de um único arquivo: no alpine cp -nnão está funcionando (e false | cp -i ...também), portanto, a solução que funciona no meu caso que eu encontrei é:

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

No exemplo acima, se o env.jsarquivo não existir, copiaremos env.example.jspara env.js.

Kamil Kiełczewski
fonte
1

Algumas versões do cp não têm a opção --no-clobber . Nesse caso:

  echo n | cp -vipr src/* dst
Otaviano
fonte