BASH: Как скопировать файл без перезаписи старых файлов

Я хотел бы знать, как скопировать файл, не перезаписывая старый файл, у меня нет доступного переключателя -n.

И cp -u, и rsync будут перезаписывать старые файлы, насколько мне известно, и я не хочу такого поведения, я хотел бы всегда сохранять старые файлы.

Спасибо


person Jim Moyle    schedule 12.07.2013    source источник
comment
если это возможно, вы можете написать небольшой скрипт, чтобы сделать это. Это мой предпочтительный метод работы. Таким образом, я могу на 100% настроить поведение.   -  person Russell Uhl    schedule 12.07.2013
comment
У вас есть опция -b?   -  person dougEfresh    schedule 12.07.2013
comment
@RussellUhl, остерегайтесь риска TOCTOU при написании скрипта.   -  person Brian Cain    schedule 12.07.2013


Ответы (3)


Вы можете использовать параметр «--interactive» (присутствует в моем cp от GNU coreutils 6.12), чтобы запросить вас перед перезаписью и заполнить его значением по умолчанию:

echo 'n' | cp --interactive ~/somefile.txt ~/somefile_already_exists.txt
person Brian Cain    schedule 12.07.2013
comment
В вопросе указывается файл, но вы правы: yes n - это более общее решение. - person Brian Cain; 12.07.2013
comment
Обратите внимание, что даже если вы используете cp -ir a/* b/ (несколько вопросов), echo 'n' | в порядке. (протестировали) Я ожидал, что echo 'n' подавит только первый вопрос ... придется исследовать это - person hek2mgl; 12.07.2013
comment
true | .. или < /dev/null достаточно, поскольку cp безопасно по умолчанию не - person that other guy; 12.07.2013

Скопируйте файл во вновь созданный временный файл в том же каталоге (см. mktemp или tempfile в Linux). Затем используйте ln, чтобы попытаться дать копии желаемое имя. ln завершится ошибкой, если имя существует; вы можете попробовать использовать другое имя или просто выдать сообщение об ошибке или что-то еще. Наконец, удалите временное имя.

person rici    schedule 12.07.2013
comment
Извините, я не хочу копировать файл (он большой), спасибо. - person Jim Moyle; 14.07.2013
comment
@JimMoyle: затем проверьте, существует ли файл, прежде чем делать это. Время от времени вы будете получать бессмысленную копию, но описанная выше атомарная копия, по крайней мере, предотвратит гонку данных. - person rici; 14.07.2013

Это неинтерактивный подход. Он проверяет, существует ли файл (после первоначального добавления случайного числа). Если это так, он ищет другое случайное число. Это можно переделать по-разному. Можно добавлять аргументы и т. Д.

   copyfile() {
      n=$RANDOM
      while [ -f $1__$n ]      
       do
       n=$RANDOM
       done
       cp $1 $1__$n
    }

использование:

copyfile file_to_copy

ваш файл будет называться примерно так:

Originalfile.txt_20625

Добавленный номер, скорее всего, предотвращает любую возможность перезаписи. Если этого недостаточно, можно добавить все, что угодно, в конец файла, например отметку времени. Если вы все еще беспокоитесь о перезаписи после этих мер, вам, вероятно, следует регулярно создавать резервные копии своих файлов.

person Bob Blogge    schedule 12.07.2013
comment
Удалить персонажей? Джим хочет не убирать, а копировать. - person dougEfresh; 12.07.2013
comment
Почему отрицательные голоса? Это копирует файл. Это смешной сайт. - person Bob Blogge; 12.07.2013
comment
@BobBlogge, вы внимательно прочитали вопрос? Если file_copy уже существует, в вашем примере он будет перезаписан. - person Brian Cain; 12.07.2013
comment
@BobBlogge Я не отрицал его, но решение выглядит немного странно. Если вы хотите скопировать файл, используйте cp .. Но вопрос был в том, как копировать файлы без перезаписи места назначения, если оно существует - person hek2mgl; 12.07.2013
comment
Ваше изменение все еще неверно. Что делать, если file_to_copy_copy уже существует? - person Brian Cain; 12.07.2013
comment
Что, если file_to_copy__$n создается после проверки в вашем while цикле, но до tr? Зачем использовать tr вместо простого cp или cat? - person Brian Cain; 12.07.2013
comment
@BrianCain Изменил его на cp. - person Bob Blogge; 15.07.2013