Як скопіювати лише атрибути файлів (метадані) без фактичного вмісту файлу?


21

Я вже копіював терабайти файлів, rsyncале забув використовувати --archiveдля збереження спеціальних атрибутів файлів.

На rsyncцей раз я спробував виконати, --archiveале це було набагато повільніше, ніж те, що я очікував. Чи є простий спосіб зробити це швидше, просто копіюючи метадані рекурсивно?


Під "метаданими" ви маєте на увазі дозволи на файли та право власності на файли чи більш складні речі, такі як розширені атрибути файлів?
Марсель Стімберг

Файлова система, де перебувають вихідні файли, встановлена ​​локально чи ні?
enzotib

під метаданими я маю на увазі дозволи та часові позначки. часові позначки для мене особливо важливі.
Мохаммед

фільтрасистема як у вихідному, так і в кінцевому напрямку монтується локально.
Мохаммед

Відповіді:


17

Добре, ви можете скопіювати власника, групу, дозвіл і тимчасові мітки з допомогою --referenceпараметра до chown, chmod, touch. Ось сценарій для цього

#!/bin/bash
# Filename: cp-metadata

myecho=echo
src_path="$1"
dst_path="$2"

find "$src_path" |
  while read src_file; do
    dst_file="$dst_path${src_file#$src_path}"
    $myecho chmod --reference="$src_file" "$dst_file"
    $myecho chown --reference="$src_file" "$dst_file"
    $myecho touch --reference="$src_file" "$dst_file"
  done

Ви повинні запустити його з sudo(щоб дозволити chown) та з двома параметрами: джерелом та адресою призначення. Сценарій лише відгукується про те, що він би робив. Якщо задоволені, змініть рядок myecho=echoна myecho=.


1
Так, це те, що мені потрібно: --референція в chmod. Дякую. І я дуже ціную це, якщо хтось міг би ввести щось на зразок chmod - посилання на копіювання часових позначок.
Мохаммед

1
@Mohammad: для цього можна скористатися touch --reference=otherfile file. Оновлено відповідь
enzotib

Це чудово. Насправді я читав посібник із сенсорних питань ;-)
Мохаммед

Лише зауваження: touchдизайн лише змінює час модифікації та доступу, час "створення" не впливає. (Я думаю, що ext2 / 3 так чи інакше не підтримує зміну ctime, але це може мати значення, якщо ви використовуєте NTFS тощо).
Amro

У випадку, якщо ви хочете змінити лише метадані існуючих файлів і не потрібно переконатись у існуванні файлів, додайте -cдо touchкоманди перемикач, щоб зупинити його створення порожніх файлів у $dst_path.
Синхро

5

ПОПЕРЕДЖЕННЯ: Без спеціальних обхідних завдань GNU cp --attributes-onlyбуде усікати цільові файли, принаймні в точності. Дивіться редагування нижче.

Оригінал:

У цій ситуації вам, мабуть, потрібна --attributes-onlyопція GNU cp разом із --archive, як це перевіреним і перевіреним кодом, виконує всі атрибути файлової системи та не слідкує за посиланнями (слідування за ними може бути поганим!):

cp --archive --attributes-only /source/of/failed/backup/. /destination/

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

Також зауважте, що якщо ви не зберегли жорсткі посилання з першого разу, rsyncале хочете зберегти їх зараз, то cp це не виправить це; вам, мабуть, найкраще попрацювати rsyncз правильними варіантами (див. моє іншу відповідь ) і набратися терпіння.

Якщо ви знайшли це запитання, шукаючи навмисне розділення та рекомбінацію вмісту метаданих / файлів, то, можливо, ви захочете поглянути на metastore який знаходиться у сховищах Ubuntu.

Джерело: Посібник з ядерних програм GNU


Відредаговано, щоб додати:

cpвід GNU coreutils> = 8.17 і вище буде працювати, як описано, але coreutils <= 8.16 буде скорочувати файли при відновленні їх метаданих. Якщо ви сумніваєтесь, не використовуйте cpв цій ситуації; використовувати rsyncз потрібними опціями і / або бути терплячим.

Я б не рекомендував цього, якщо ви повністю не зрозумієте, що ви робите, але раніше GNU cpможна запобігти обрізанню файлів за допомогою трюку LD_PRELOAD :

/*
 * File: no_trunc.c
 * Author: D.J. Capelis with minor changes by Zak Wilcox
 *
 * Compile:
 * gcc -fPIC -c -o no_trunc.o no_trunc.c
 * gcc -shared -o no_trunc.so no_trunc.o -ldl
 *
 * Use:
 * LD_PRELOAD="./no_trunc.so" cp --archive --attributes-only <src...> <dest>
 */

#define _GNU_SOURCE
#include <dlfcn.h>
#define _FCNTL_H
#include <bits/fcntl.h>

extern int errorno;

int (*_open)(const char *pathname, int flags, ...);
int (*_open64)(const char *pathname, int flags, ...);

int open(const char *pathname, int flags, mode_t mode) {
        _open = (int (*)(const char *pathname, int flags, ...)) dlsym(RTLD_NEXT, "open");
        flags &= ~(O_TRUNC);
        return _open(pathname, flags, mode);
}

int open64(const char *pathname, int flags, mode_t mode) {
        _open64 = (int (*)(const char *pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64");
        flags &= ~(O_TRUNC);
        return _open64(pathname, flags, mode);
}

errornoмає бути errno, правда?
enzotib

Швидке видалення тесту, здається, спрацьовує, тому я гадаю, що я увічнив надмірність / помилку в оригіналі , але все-таки всі будуть в більш нових ядрах.
ZakW

але те, що ви називаєте rsyncправильними варіантами, - це відповідь на інше питання ...
Жан Пол

5

Розглядаючи питання як "rsync, лише метадані копіюються, так чому це так повільно, і як я можу зробити це швидше?":

rsyncзазвичай використовує рівні тривалість часу як евристику для виявлення та пропуску незмінних файлів. Без --archive(конкретно, без --times) mtimes файлів призначення залишається встановленим на час, коли ви їх синхронізували, тоді як mtimes вихідних файлів залишається неушкодженим (ігноруючи ручне хитрість вами). Без зовнішніх гарантій того, що вміст вихідних файлів не змінився, rsync повинен припустити, що він може бути, і тому він повинен перевірити їх та / або скопіювати їх до місця призначення знову. Це, плюс той факт, що --whole-fileмається на увазі для локальних> локальних синхронімів, робить rsyncбез --timesприблизно еквівалентнимcp місцевих синхронізацій.

За умови прийняття оновлення вмісту файлів призначення або якщо вихідні файли не торкнулися з початкової копії, ви повинні знайти rsync --archive --size-onlyшвидше, ніж наївний rsync.

Якщо ви сумніваєтесь у тому, що rsyncтаке копіювання триває так довго, rsync --archive --dry-run --itemize-changes ...ви розповідаєте вичерпно, якщо коротко, детально.


1
Дуже корисна інформація. --archive - лише для великого розміру - чудова комбо. Це не тільки запобігає повторному копіюванню файлів, які вже є в пункті призначення, але й оновить їх метадані. Для мене це було несподівано, тому що man's page rsync описує --size-only як "пропускаючі" файли, розміри яких відповідають. Виявляється, вона просто пропускає копію, але все одно буде синхронізувати метадані. Ідеально.
Чад фон Нау

2

У локальних передачах, коли джерело та призначення знаходяться на локально встановлених файлових системах, rsyncзавжди буде копіюватися вміст цілих файлів. Щоб уникнути цього, ви можете скористатися

rsync -a --no-whole-file source dest

Я спробував rsync з --no-full-file та --progress, і я все ще бачу хід копіювання (близько 30 Мб / с); тож я здогадуюсь, що це не досить швидко. Я втрачаю надію на rsync ...
Мохаммед

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

2

Мені довелося це робити віддалено на інший комп'ютер, щоб я не міг використовувати --reference

Я використовував це для створення сценарію ...

find -printf "touch -d \"%Tc\" \"%P\"\n" >/tmp/touch.sh

Але переконайтеся, що в них спочатку немає файлових назв "

find | grep '"'

Потім скопіюйте touch.sh на віддалений комп'ютер і запустіть ...

cd <DestinationFolder>; sh /tmp/touch.sh

Також є параметри find -printf для друку користувача, ім'я групи, якщо ви хочете скопіювати їх.


Дякуємо за ідеї до а) "просто використовувати скрипт оболонки" та б) для створення вказаного сценарію за допомогою find. Я опинився в тій же ситуації - забув скопіювати атрибути, джерела та диски призначення, які вже були на різних машинах, і не дуже хотів це перевертати.
i336_
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.