Линукс как копировать а не перезаписать?

386

Я хочу cpкаталог, но я не хочу перезаписывать любые существующие файлы, даже если они старше, чем скопированные файлы. И я хочу сделать это абсолютно неинтерактивным, так как это будет частью скрипта Crontab Bash. Любые идеи?

mnowotka
источник

Ответы:

589

Взято из справочной страницы :

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

Пример:

cp -n myoldfile.txt mycopiedfile.txt
hovanessyan
источник
33
Обратите внимание, это завершится с ошибкой, если файл существует. Чтобы выйти с успехом, попробуйте cp -n source.txt destination.txt || true
galenandrew
13
@galenandrew cp -nне завершается с ошибкой, если файл существует в Ubuntu 12.04.
amit
@galenandrew Подтверждено. Спасибо. Мой проект не создавался в Xcode после добавления сценария запуска к моей цели.
Руиз
@AaronFranke выглядит так, как будто это так.
Борис
93

Подумайте об использовании rsync.

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

Согласно комментариям rsync -a -v src dstэто не правильно, потому что он будет обновлять существующие файлы.

Ханс Гинзел
источник
7
Вы хотите добавить --ignore-existingфлаг, чтобы предотвратить перезапись существующих файлов.
Все работники необходимы
7
Полная команда rsync -a -v --ignore-existing <src> <dst>действительно правильный ответ, а не cp -uвыше.
Whitebird
Если предыдущая копия была прервана и скопирован только усеченный файл, я уверен, что cp -u не скопирует его повторно ... но будет ли rsync с --ignore-существующие? Наверное, нет ... так что это делает их совершенно эквивалентными, верно?
Dagelf
rsync сохраняет временную метку файла, в то время как cp использует текущее время (по моему опыту)
Stefan Diabo
1
на некоторых серверах просто нет rsync
mebada
51
cp -n

Это то, что вы хотите. Смотрите справочную страницу.

хвастливый
источник
@AaronFranke да, это будет работать рекурсивно.
Борис
33

Это будет работать на RedHat:

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

Обновление, а не перезапись это нечто другое.

ceving
источник
4
Что falseздесь делать?
Замороженное пламя
11
@FrozenFlame Отвечает на -iвопросы.
выступление
Очевидно, что эта команда не будет работать, если вы попытаетесь скопировать больше, чем файлы ARG_MAX. Чтобы обойти это дело, проверьте эту ссылку .
Мджиниус
2
Также очевидно, что эта команда не будет работать, если земля упадет на солнце.
ceving
32

Для людей, которые находят, что у них нет опции 'n' (как я в RedHat), вы можете использовать, cp -uчтобы записать файл, только если источник новее, чем существующий (или не существует).

[edit] Как уже упоминалось в комментариях, это перезапишет старые файлы, поэтому не совсем то, что хотел ОП. Используйте ответ ceving для этого.

Грим ...
источник
11
OP попросил не перезаписывать существующие файлы, даже если они старше, чем скопированные файлы , поэтому на -uсамом деле не соответствует цели.
Эндрю Лотт
4
Боже мой, ты абсолютно прав. Я удивлен, что так долго никто не заметил.
Мрачно ...
Возможно, это не то, о чем просил OP, но это именно то, что мне нужно для моего Uberspace (Centos 7). Спасибо!
Томас Праксл
Я рад, что шесть лет назад я мог помочь :-D
...
10

Alpine Linux: ниже ответ только для случая одного файла: в Alpinecp -n не работает (и false | cp -i ...тоже), поэтому решение, работающее в моем случае, которое я нашел, это:

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

В приведенном выше примере, если env.jsфайл не существует, мы копируем env.example.jsв env.js.

Камил Келчевски
источник
1

Некоторые версии cp не имеют опции --no-clobber . В таком случае:

  echo n | cp -vipr src/* dst
Октавиан
источник