2

Я пытаюсь использовать tar для резервного копирования моих файлов. При --exclude=/proc/ архив содержит файлы в каталоге /proc, а --exclude=/proc - нет. Что вызывает разницу?

PS Я использую оболочку Bash.

2 ответа2

3

Обычно дело доходит до соглашения программы. С (GNU) tar это немного противоречиво, потому что завершающий / не меняет включенные каталоги. Поведение частично объясняется здесь « шаблоны и имена используются как есть ». Исключения могут соответствовать любой части имени (если вы не используете --anchor).

Документация не ясно, что есть разница, или почему.

Внутренне причина, по которой конечный / не совпадает в исключении, заключается в том, что tar использует opendir(3) , readdir(3) и fnmatch(3) - opendir() принимает конечный / в каталоге, readdir() не делает косая черта в именах каталогов, а fnmatch() просто сопоставляет шаблоны без учета существующих файлов или канонизации. В частности, fnmatch("proc/","proc",0) возвращает 1 (без совпадения).

Сравните rsync который имеет очень четкие (и хорошо документированные) различия для конечных / имен каталогов.

Связанная проблема заключается в том, что иногда вы хотите сделать резервную копию каталога, потому что это точка монтирования, хотя вам не нужно его содержимое. Предполагается, что ваша резервная копия может содержать все необходимые точки монтирования (/dev proc /sys ), поэтому обычно вы захотите сделать следующее:

tar --exclude=/proc/* --exclude=/sys/* --exclude=/dev/* [...]
2

На самом деле нет большой разницы между использованием конечной косой черты или вообще отсутствием для каталога, за исключением обработки символических ссылок. См. Базовые спецификации открытых групп, 4.11 Разрешение пути (также см. Этот ответ в Unix SE).

Что касается GNU tar: завершающий слеш просто не обрабатывается в шаблонах --exclude , как вы заметили. Разница просто вызвана его конкретным исходным кодом, если нужно на что-то указывать :-). Посмотрите этот вопрос на Server Fault SE (хотя он не дает много подробностей - он просто констатирует факт). Посмотрите эту ветку для получения дополнительной информации. Подсказка может быть найдена в этом отрывке (хотя я не совсем уверен, что с этим делать):

Отто Моербик написал:

Это кусок кода, который имеет отношение:

            /*
             * Some programs that create ustar archives append a '/'
             * to the pathname for directories. This clearly violates
             * ustar specs, but we will silently strip it off anyway. 
             */
            if (arcn-> name[arcn-> nlen - 1] == '/')
                    arcn-> name[--arcn-> nlen] = '\0';

Как вы можете видеть с помощью hexdump -C архивов, созданных gtar, gtar - такая программа. Я не чувствую, что меняю tar только для того, чтобы приспособить несоответствующие программы.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .