scp без замены существующих файлов в месте назначения

158

Как скопировать весь каталог в одноименный каталог без замены содержимого в целевом каталоге? (вместо этого я хотел бы добавить к содержимому папки назначения)

Даниэль Бёмер
источник
Да, это раздражает , когда полезная программа / утилита не имеет , что один « если только он мог ...» вариант! В этом случае "--noclobber"!
MikeW

Ответы:

140

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

rsync -au /local/directory/ host:/remote/directory/
rsync -a --ignore-existing /local/directory/ host:/remote/directory/

(Обратите внимание /на исходную сторону: без этого rsyncсоздастся /remote/directory/directory.)

жилль
источник
@ Антон, я не понимаю твой комментарий и не вижу ответа или комментария от Чандры. --ignore-existingдобавить без замены, какую потерю данных вы видите?
Жиль
Извините, я только посмотрел на ваш первый пример, где вы можете потерять данные (и, по-моему, это не то, о чем просил OP), если вы включите --ignore-существующие потери данных не должны произойти.
Anthon
Это не поможет, если удаленная система не будет rsyncлегко доступна .... (Как Win32-OpenSSH)
Герт ван ден Берг
@GertvandenBerg rsync довольно просто установить в Windows, не сложнее, чем SSH.
Жиль
@Gilles: Да, но все опции, похоже, включают в себя библиотеки Cygwin DLL ... (Текущее состояние порта MS OpenSSH таково, что включения сжатия на scp достаточно, чтобы сломать SCP ...) (Получение функциональности rsync поверх Win32 -OpenSSH также кажется нетривиальным - надеюсь, со временем это улучшится) (другой пример - Solaris 10, где требуется сторонний пакет --rsync-path)
Герт ван ден Берг
82

scp перезапишет файлы, если у вас есть права на запись в них.

Другими словами: Вы можете scpэффективно пропустить указанные файлы, временно удалив разрешения на запись для них (если вы являетесь владельцем файлов, то есть).

Reimund
источник
5
Спасибо за это. Это был именно тот трюк, который я искал.
сахарин
убедитесь, что вы скопировали файлы обратно, добавив * для этого. Примерscp -r user@server.com:/location/of/files/* /local/location/
Рик
1
находить . -type f -exec chown root: root {} \;
Лин
1
В редких случаях, когда ожидается перезапись только некоторых файлов в каталоге (если они не «защищены»), а права доступа к файлам не одинаковы для разных файлов, это решение может не работать. В остальном это довольно просто и эффективно.
sancho.s
Для этого на окнах выберите все файлы, щелкните правой кнопкой мыши -> Свойства -> Только для чтения
BenJammin
12

Вы можете копировать только новые файлы по дате. использованиеfind

scp  `find /data/*.gz -type f -mtime +7` USER@SERVER:/backup/
Naks
источник
что значит +7?
Фрэнсис Ким
@FrancisKim это значит измененный 7 дней назад. Так что в этом запросе выбираются любые файлы * .gz, измененные за последние 7 дней
Вадим Еремеев
4
На самом деле +7 не означает более 7 дней назад?
Джефф Х.
1
Да, это означает «более 7 дней назад». Понятия не имею, кто проголосовал за это.
Стефан Райх
9

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

find . -type f -exec chmod a-w '{}' \;

перед запуском scp(будет пожаловаться и пропустить существующие файлы).

И измените их обратно потом ( chmod +wчтобы получить значение на основе масок). Если не все файлы имеют разрешение на запись в соответствии с вашей маской, вам нужно каким-то образом хранить разрешения, чтобы их можно было восстановить.

(Ответ Жиля перезаписывает существующие файлы, если локально они более новые, я потерял ценные данные таким образом. Не понимаю, почему этот неправильный и вредный ответ имеет так много голосов).

Mohad
источник
2
Я не понимаю: как rsync --ignore-existingвы потеряли данные?
Жиль
4
Я получил ошибку , find: missing argument to '-exec'используя эту команду, а вместо этого пришлось использовать: find . -type f -exec chmod a-w {} \;. Мой Linux плох, мммм.
wpearse
Это лучший и безопасный ответ. Правильная команда для изменения разрешения выглядит как @wpearse:find . -type f -exec chmod a-w {} \;
Амир
6

У меня была похожая задача, в моем случае я не мог использовать rsync, csyncили FUSE , потому что мое хранилище имеет только SFTP. rsyncНе удалось изменить дату и время для файла, некоторые другие утилиты (например csync) показывали мне другие ошибки: « Невозможно создать временный файл Обнаружен перекос часов ».

Если у вас есть доступ к хранилищу-серверу - просто установите openssh-serverили запустите здесь rsyncкак демон.

В моем случае - я не мог этого сделать, и решение было: lftp . lftpИспользование для синхронизации приведено ниже:

lftp -c "open -u login,password sftp://sft.domain.tld/; \
    mirror -c --verbose=9 -e -R -L /srs/folder /rem/folder"

/src/folder- это папка на моем компьютере, /rem/folder- есть sftp://sft.domain.tld/rem/folder.

Вы можете найти справочные страницы по ссылке: http://lftp.yar.ru/lftp-man.html

жирный
источник
6

Чтобы скопировать целую кучу файлов, их быстрее смолить. Используя -k, вы также предотвращаете перезапись файлов при распаковке в целевой системе.

tar -c <source-dir> | ssh <name>@<host> 'tar -kxzf - -C <target-dir>' 
huembi
источник
1
Это делает удаленное соединение. Сначала это tar, источник, направляет его в ssh-соединение и распаковывает его в удаленной системе.
huembi
-1

scpперезаписывает файлы, и нет никакого переключателя, чтобы остановить это, но вы можете скопировать все как есть, выполнить scp, а затем скопировать существующие файлы обратно. Примеры:

  1. Скопируйте все существующие файлы в путь

    mkdir original_files ; cp -r * original_files/
    
  2. Скопируйте все используя scp

    scp -r user@server:dir/* ./
    
  3. Скопируйте исходные файлы поверх всего, что написал scp:

    cp -r original_files/* ./
    
A.Badger
источник
3
Этот метод не помогает, когда вы пытаетесь извлечь файлы с пульта и выбрать, где вы остановились. Т.е. если вся цель сэкономить время.
Оливер Уильямс
-1

Еще один способ добиться этого - создать lsпапку назначения:

В папке удаленного назначения:

ls | awk '{print "mv " $1 " ../copied_data/"}' > mv_copied_data
scp mv_copied_data user@source.server.com:/path/to/source/folder

По источнику:

cd /path/to/source/folder
chmod 777 mv_copied_data
./mv_copied_data

По назначению:

scp -r user@source.server.com:/path/to/source/folder /path/to/destination/foldeer
Самир Гурджар
источник
Пожалуйста, не делай этого. 1. Не разбирайте ls . 2. Ответ опасен, если любое имя файла содержит - >пробел новой строки или другие специальные символы. 3. Жесткий код цикла for в скрипте Python. Генерировать программу во время выполнения сложно и сложно (даже если это делают профессиональные программисты) по многим причинам. Создание сценария оболочки еще хуже - ужасная идея.
Ignis