Я уже скопировал терабайты файлов с rsync
но я забыл использовать --archive
сохранить специальные атрибуты файлов.
Я пытался выполниться rsync
снова на этот раз с --archive
но это был путь медленнее, чем, что я ожидал. Там какой-либо простой способ состоит в том, чтобы сделать это быстрее, просто копируя метаданные рекурсивно?
Хорошо, можно скопировать владельца, группу, разрешение и метки времени с помощью --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
(для разрешения показанный) и с двумя параметрами: источник и целевой каталог. Сценарий только повторяет то, что он сделал бы. Если удовлетворенное изменение строка myecho=echo
с myecho=
.
В локальных передачах, когда источник и место назначения находятся в локально смонтированных файловых системах, rsync
будет всегда копировать целое содержание файлов. Для предотвращения этого, можно использовать
rsync -a --no-whole-file source dest
ПРЕДУПРЕЖДЕНИЕ: Без специальных обходных решений, GNU cp --attributes-only
усечет целевые файлы, по крайней мере, в Точном. Посмотрите редактирование ниже.
Исходный:
В этой ситуации Вы, вероятно, хотите CP GNU --attributes-only
опция, вместе с --archive
, поскольку это - проверенный на практике код, делает все агностические файловой системой атрибуты и не следует, символьные ссылки (после них может быть плохим!):
cp --archive --attributes-only /source/of/failed/backup/. /destination/
Как с файлами, cp
дополнение с расширенными атрибутами: если и источник и место назначения расширили атрибуты, он добавляет расширенные атрибуты источника к месту назначения (вместо того, чтобы удалить все xattrs места назначения сначала). В то время как это зеркально отражает как cp
ведет себя, если Вы копируете файлы в существующее дерево, это не могло бы быть тем, что Вы ожидаете.
Также обратите внимание на это, если Вы не сохранили жесткие ссылки в первый раз вокруг с rsync
но хочу сохранить их теперь затем cp
не зафиксирует это для Вас; Вы являетесь, вероятно, лучшими от повторного выполнения rsync
с правильными опциями (см. мой другой ответ), и быть терпеливым.
Если Вы нашли этот вопрос, в то время как смотрящий сознательно отдельный и содержание метаданных/файла переобъединения затем Вы могли бы хотеть смотреть на метахранилище, которое находится в репозиториях Ubuntu.
Источник: GNU coreutils руководство
Отредактированный для добавления:
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);
}
Обработка вопроса как "rsync только имеет метаданные для копирования, итак, почему это настолько медленно, и как я могу сделать его быстрее?":
rsync
обычно использование равняется mtimes как эвристике, чтобы обнаружить и пропустить неизменные файлы. Без --archive
(а именно, без --times
) mtimes целевых файлов остаются установленными на время Вы rsync-редактор их, в то время как mtimes исходных файлов остаются неповрежденными (игнорирование ручного обмана Вами). Без внешних гарантий от Вас, которых не изменило содержание исходных файлов, rsync должен предположить, что они могли бы иметь и поэтому имеют к контрольной сумме их, и/или скопируйте их в место назначения снова. Это, плюс факт это --whole-file
подразумевается для локального-> локальные синхронизации, делает rsync
без --times
приблизительно эквивалентный cp
для локальных синхронизаций.
При условии, что обновление содержания целевых файлов приемлемо, или если исходные файлы являются нетронутыми начиная с оригинала, необходимо найти rsync --archive --size-only
более быстрый, чем наивный rsync.
Если в сомнении, относительно какой rsync
копирует, который занимает много времени, rsync --archive --dry-run --itemize-changes ...
говорит Вам в исчерпывающем, если краткий, детали.
Я должен был сделать это удаленно к другому компьютеру, таким образом, я не мог использовать - ссылка
Я использовал это для создания сценария...
find -printf "touch -d \"%Tc\" \"%P\"\n" >/tmp/touch.sh
Но удостоверьтесь, что нет никаких имен файлов с "в них сначала...
find | grep '"'
Затем скопируйте touch.sh в свой удаленный компьютер и работайте...
cd <DestinationFolder>; sh /tmp/touch.sh
Существуют также опции в находке-printf для печати пользователя, название группы, если Вы хотите, копирует их.