Як синхронізувати лише певний список файлів?


95

У мене близько 50 файлів у різних підкаталогах, які я хотів би перенести на віддалений сервер. Я припустив, що rsync зможе зробити це за мене, використовуючи параметр --include-from. Без опції --exclude = "*" усі файли в каталозі синхронізуються, а з опцією файли відсутні.

rsync -avP -e ssh --include-from=deploy/rsync_include.txt --exclude=* ./ root@0.0.0.0:/var/www/ --dry-run

Спочатку я запускаю його як сухий, і 0.0.0.0, очевидно, замінюється IP віддаленого сервера. Вміст rsync_include.txt - це новий список відносних шляхів до файлів, які я хочу завантажити, відокремлений рядком.

Чи є кращий спосіб зробити це, щоб уникнути мене в понеділок вранці?

Відповіді:


3

Редагувати: відповідь Йосипа Родена нижче є кращою. Будь ласка, використовуйте його!

Можливо, вам буде простіше, якщо ви шукаєте певний список файлів, а замість цього розміщуєте їх безпосередньо в командному рядку:

# rsync -avP -e ssh `cat deploy/rsync_include.txt` root@0.0.0.0:/var/www/

Однак це передбачає, що ваш список не такий довгий, що довжина командного рядка буде проблемою, і що rsync_include.txtфайл містить лише реальні шляхи (тобто без коментарів і без регулярних виразів).


9
На жаль, це не працює з великим списком або з файлами з пробілами в назві.
Wes Modes

3
[Список аргументів занадто довгий]
Данко Давід,

За замовчуванням xargs додає аргументи з stdin до кінця командного рядка. Це не працює, оскільки rsync потрібен останній аргумент для призначення. Деякі версії xargs можуть замість цього вставляти аргументи в середину командного рядка. Це має працювати, доки ви не проти, що він може запускати rsync більше одного разу, коли список файлів довгий. У будь-якому випадку, rsync --files-fromце, мабуть, простіше і надійніше рішення :)
Лассі,

Вес Хардакер: Чи справді ваше редагування та посилання на "відповідь Йосипа Родена" стосується відповіді @atp, яку редагував Роден?
Шеймус

234

Є прапор, --files-fromякий робить саме те, що ти хочеш. Від man rsync:

--files-from=FILE

Використання цієї опції дозволяє вказати точний список файлів для передачі (як прочитаний із вказаного ФАЙЛУ або - для стандартного введення). Він також налаштовує поведінку rsync за замовчуванням, щоб полегшити передачу лише вказаних файлів і каталогів:

  • Мається на увазі параметр --relative (-R), який зберігає інформацію про шлях, вказану для кожного елемента у файлі (використовуйте --no-relative або --no-R, якщо ви хочете це вимкнути).

  • Мається на увазі параметр --dirs (-d), який створюватиме каталоги, вказані у списку в пункті призначення, а не шумно їх пропускатиме (використовуйте --no-dirs або --no-d, якщо ви хочете це вимкнути).

  • Поведінка параметра --archive (-a) не передбачає --recursive (-r), тому вкажіть це явно, якщо ви цього хочете.

  • Ці побічні ефекти змінюють стан rsync за замовчуванням, тому позиція параметра --files-from у командному рядку не впливає на аналіз інших параметрів (наприклад -a працює однаково до або після --files- від, як і --no-R та всі інші варіанти).

Усі імена файлів, які зчитуються з ФАЙЛУ, відносяться до вихідної директорії - будь-які провісні скісні риски видаляються, і жодні посилання ".." не можуть перевищувати вихідну директорию. Наприклад, візьміть цю команду:

rsync -a --files-from=/tmp/foo /usr remote:/backup

Якщо / tmp / foo містить рядок "bin" (або навіть "/ bin"), каталог / usr / bin буде створений як / backup / bin на віддаленому хості. Якщо він містить "bin /" (зверніть увагу на косу риску), безпосередній вміст каталогу також буде надіслано (без необхідності явного згадування у файлі - це почалося у версії 2.6.4). В обох випадках, якщо параметр -r був увімкнений, вся ієрархія цього каталогу також була б передана (майте на увазі, що -r потрібно вказувати явно за допомогою --files-from, оскільки це не означає -a). Також зауважте, що ефект (увімкнено за замовчуванням) --relative - дублювати лише інформацію про шлях, що зчитується з файлу, - це не примушує дублювати шлях до специфікації джерела (/ usr у цьому випадку) .

Крім того, файл --files-from можна читати з віддаленого хоста замість локального, якщо перед файлом вказано "host:" (хост повинен відповідати одному кінці передачі). Як ярлик можна вказати лише префікс ":", що означає "використовувати віддалений кінець передачі". Наприклад:

rsync -a --files-from=:/path/file-list src:/ /tmp/copy

Це скопіює всі файли, зазначені у файлі / path / file-list, який знаходився на віддаленому хості "src".

Якщо вказані параметри --iconv та --protect-args, а імена файлів --files-from надсилаються з одного хоста на інший, імена файлів будуть перекладені з набору символів хосту, що надсилає, на набір символів хосту, що отримує.

ПРИМІТКА: сортування списку файлів у вхідному файлі --files-from допомагає rsync бути ефективнішим, оскільки це дозволить уникнути повторного відвідування елементів шляху, які спільно використовуються між сусідніми записами. Якщо введення не відсортовано, деякі елементи шляху (маються на увазі каталоги) можуть закінчитися скануванням кілька разів, і rsync врешті-решт дублюватиме їх після того, як вони перетворяться в елементи списку файлів.


23
Зверніть увагу, що вам все одно доведеться вказати каталог, де знаходяться перелічені файли, наприклад: rsync -av --files-from=file-list . target/для копіювання файлів із поточного каталогу.
Ніколас Маттіа

7
Так, і ще раз заявити: The filenames that are read from the FILE are all relative to the source dir.
atp

Ах, пропустив це, вибачте!
Ніколас Маттіа

1
якщо у файлі files-from є що-небудь, що починається з ..rsync, схоже, ігнорує ..видачу помилки rsync: link_stat "/home/michael/test/subdir/test.txt" failed: No such file or directory(наприклад, у цьому випадку запускається з "тестового" каталогу і намагається вказати "../subdir/test.txt", який існує.
Michael

Чи може --files-fromаргумент поєднуватися з явним списком включає та виключає, і чи будуть файли зі списку, доданого разом із --files-fromзаміненими, існуючими правилами виключення, такими, що вони будуть включені, якщо вони з’являться у файлі?
highsciguy

13

--files-from=параметру потрібна коса коса риса, якщо ви хочете зберегти абсолютний шлях незмінним. Отже, ваша команда стане приблизно такою, як показано нижче:

rsync -av --files-from=/path/to/file / /tmp/

Це можна зробити так, ніби існує велика кількість файлів, і ви хочете скопіювати всі файли в шлях x. Отже, ви знайдете файли і перекинете вивід у файл, як показано нижче:

find /var/* -name *.log > file

9

Для запису, жодна з наведених вище відповідей не допомогла, крім однієї. Підводячи підсумок, ви можете зробити операцію резервного копіювання за допомогою--files-from= , використовуючи:

 rsync -aSvuc `cat rsync-src-files` / mnt / d / rsync_test /

АБО

rsync -aSvuc --recursive --files-from = rsync-src-files. / mnt / d / rsync_test /

Перша команда сама собою пояснюється, окрім вмісту файлу, rsync-src-filesякий я детально розгляну нижче. Тепер, якщо ви хочете використовувати останню версію, вам слід мати на увазі наступні чотири зауваження:

  1. Зверніть увагу, що потрібно вказати як каталог, так --files-fromі джерело
  2. Потрібно чітко вказати --recursive .
  3. Файл rsync-src-files - це створений користувачем файл, і він був поміщений в каталог src для цього тесту
  4. rsyn-src-filesУтримувати файли і папки для копіювання , і вони приймаються відносно вихідного каталогу. ВАЖЛИВО: Переконайтеся, що у файлі немає пробілів чи порожніх рядків. У наведеному нижче прикладі є лише два рядки, а не три (зрозуміти це випадково). Зміст rsynch-src-files:

folderName1
folderName2


3

Я отримав подібне завдання: rsync всі файли, змінені після заданої дати, але виключаючи деякі каталоги. Було складно побудувати один лайнер "все в одному", тому я занурив проблему на менші шматки. Остаточне рішення:

find  ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | egrep -v "/\..|Downloads|FOO" > FileList.txt
rsync -v --files-from=FileList.txt ~/sourceDIR /Destination

Спочатку використовую find -L ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS". Я спробував додати regexдо findрядка, щоб виключити шаблони імен, однак мій смак Linux (Mint), не розуміючи, заперечує регулярне вираження find. Перевірена кількість ароматів регулярного виразу - не працює за бажанням. Тож я закінчую egrep -v- варіантом, який виключає простий спосіб малювання. Мої rsyncне копіювати каталоги як /.cache або /.config плюс деякі інші я явно по імені.


1
Я вважаю, що ви можете використати заміну процесу, щоб перетворити це на bashrsync -v --files-from=<(find ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | grep -Ev "/\..|Downloads|FOO") ~/sourceDIR /Destination
однокласний

2
$ date
  Wed 24 Apr 2019 09:54:53 AM PDT
$ rsync --version
  rsync  version 3.1.3  protocol version 31
  ...

Синтаксис: rsync <file_/_folder_list> <source> <target>

Імена папок (тут, З кінцевим завершенням /; наприклад Cancer - Evolution/) містяться у файлі списку папок (наприклад: cm_folder_list_test):

# /mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test
# test file: 2019-04-24
Cancer/
Cancer - Evolution/
Cancer - Genomic Variants/
Cancer - Metastasis (EMT Transition ...)/
Cancer Pathways, Networks/
Catabolism - Autophagy; Phagosomes; Mitophagy/
Catabolism - Lysosomes/

Якщо ви не включите ці кінцеві /, цільові папки rsync'd будуть створені, але порожні.

Ці імена папок додаються до решти шляху ( /home/victoria/Mail/2_RESEARCH - NEWS), таким чином забезпечуючи повний шлях до папки до rsync; наприклад: /home/victoria/Mail/2_RESEARCH - NEWS/Cancer - Evolution/.

Зверніть увагу, що вам також потрібно використовувати --files-from=..., НЕ --include-from=...

rsync -aqP --delete --files-from=/mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test "/home/victoria/Mail/2_RESEARCH - NEWS" $IN/

(У своєму сценарії BASH я визначив змінну $INнаступним чином.)

BASEDIR="/mnt/Vancouver/projects/ie/claws"
IN=$BASEDIR/data/test/input

Використані параметри rsync:

 -a  :   archive: equals -rlptgoD (no -H,-A,-X)
    -r  :   recursive
    -l  :   copy symlinks as symlinks
    -p  :   preserve permissions
    -t  :   preserve modification times 
    -g  :   preserve group 
    -o  :   preserve owner (super-user only) 
    -D  :   same as --devices --specials 
  -q  :   quiet (/server/547106/run-totally-silent-rsync)

  --delete
    This  tells  rsync to delete extraneous files from the RECEIVING SIDE (ones
    that AREN’T ON THE SENDING SIDE), but only for the directories that are
    being synchronized.  You must have asked rsync to send the whole directory
    (e.g.  "dir" or "dir/") without using a wildcard for the directory’s contents
    (e.g. "dir/*") since the wildcard is expanded by the shell and rsync thus
    gets a request to transfer individual files, not the files’ parent directory.
    Files  that  are  excluded  from  the transfer are also excluded from being
    deleted unless you use the --delete-excluded option or mark the rules as
    only matching on the sending side (see the include/exclude modifiers in the
    FILTER RULES section).  ...

1

Ця відповідь не є прямою відповіддю на питання. Але це повинно допомогти вам з’ясувати, яке рішення найкраще підходить для вашої проблеми.

При аналізі проблеми слід активувати опцію налагодження -vv

Потім rsync видасть, які файли включені або виключені за яким шаблоном:

building file list ... 
[sender] hiding file FILE1 because of pattern FILE1*
[sender] showing file FILE2 because of pattern *

0

Жодна з цих відповідей не спрацювала для мене, коли все, що я мав, - це список каталогів . Тоді я натрапив на рішення! Ви повинні додати -rдо , --files-fromтому що -aНЕ буде рекурсивним в цьому випадку (хто знав?!).

rsync -aruRP --files-from=directory.list . ../new/location

Якщо ви вказали “dir” у файлі, вам потрібно вказати -r / —recursive; якщо ви вказали "dir /", ви цього не робите.
lbutlr
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.