Учитывая древовидную структуру с файлами в ней, скажите:
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/