Назад | Перейти на главную страницу

tar --listed-incremental включает все каталоги в каждом приращении?

Учитывая древовидную структуру с файлами в ней, скажите:

source
|-- bar
|   +-- three.txt
|-- baz
|   +-- four.txt
+-- foo
    |-- one.txt
    +-- two.txt

Если я сделаю

tar czvf dest/archive-1.tgz --listed-incremental dest/archive.snar source/*

Это создает .tgz файл, содержащий все текущие файлы и папки, именно то, что я ожидал:

source/bar/
source/baz/
source/foo/
source/bar/three.txt
source/baz/four.txt
source/foo/one.txt
source/foo/two.txt

Если я сразу сделаю:

tar czvf dest/archive-2.tgz --listed-incremental dest/archive.snar source/*

Кажется, что это создает .tgz файл, содержащий все подпапки текущего каталога, без файлов:

source/bar/
source/baz/
source/foo/

Я не этого хочу. В игрушечном примере, подобном этому, это не так уж плохо, но в большой структуре папок намного сложнее сказать, что .tgz по существу пуст. Это много шума. В идеале, tar сообщит мне, что обновленных файлов нет, и выйдет с кодом ошибки, но даже если бы он создал пустой tar, это было бы лучше (в данном случае для меня), чем архив с множеством пустых папок.

Есть ли способ сделать tar --listed-incremental вести себя так, как я хочу? Я сделал несколько поисков, чтобы найти решения, но не нашел.

Я могу просто перестать использовать --listed-incremental и работаю с find вместо этого составить список файлов, но это намного сложнее, если есть способ сделать --listed-incremental делаю что хочу. Какие-либо предложения?

На странице руководства упоминается:

При извлечении из инкрементной резервной копии GNU tar пытается восстановить точное состояние файловой системы на момент создания архива. В частности, он удалит те файлы в файловой системе, которые не существовали в их каталогах при создании архива.

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

Отредактировано в попытке уточнить ответ:

Пример 1: Расширение исходного примера ...

Шаг 1. Удалите один из существующих файлов и создайте дополнительный архив.

$ rm source/foo/two.txt
rm: remove regular empty file `source/foo/two.txt'? y

$ tar czvf dest/archive-3.tgz --listed-incremental dest/archive.snar source/*
source/bar/
source/baz/
source/foo/

Шаг 2: воссоздайте предыдущий файл в foo

$ touch source/foo/two.txt

Шаг 3: Извлеките инкрементный архив, который удалит только что созданный файл (он знает, что этот файл отсутствовал в исходном архиве, поскольку запись каталога source / foo /, включенная в архив, не упоминает о нем в своей таблице -of-содержимого ")

$ tar xvfz dest/archive-3.tgz --listed-incremental dest/archive.snar
source/bar/
source/baz/
source/foo/
tar: Deleting `source/foo/two.txt'

Пример 2: Включая каталог верхнего уровня, где каталог foo (и его файлы) будут удалены, если они отсутствуют в инкрементном архиве.

Шаг 1. Создайте исходный архив, используя «source», а не «source / *»

$ tar czvf dest/archive-1.tgz --listed-incremental dest/archive.snar source
source/
source/bar/
source/baz/
source/foo/
source/bar/three.txt
source/baz/four.txt
source/foo/one.txt
source/foo/two.txt

Шаг 2: Удалите каталог foo и создайте инкрементный архив, не содержащий ссылки на foo.

$ rm -rf source/foo
$ tar czvf dest/archive-2.tgz --listed-incremental dest/archive.snar source
source/
source/bar/
source/baz/

Шаг 3. Восстановите каталог foo

$ mkdir source/foo
$ touch source/foo/one.txt
$ touch source/foo/two.txt

Шаг 4: Извлеките архив (в этот момент foo будет удален, так как он не отображается в «оглавлении» для записи «source /».

$ tar xzvf dest/archive-2.tgz --listed-incremental dest/archive.snar source
source/
tar: Deleting `source/foo'
source/bar/
source/baz/