tar --compare: как сверить архив с исходным каталогом до очистки
Воспроизводимая проверка GNU tar 1.35: сравниваем архив с каталогом без распаковки поверх данных, различаем коды 0, 1 и 2 и показываем важную границу — лишний файл команда не замечает.

В этой статье
- Входные условия
- Подготавливаем безопасный стенд
- Первое сравнение: архив и каталог совпадают
- Изменение одного байта при прежнем размере и времени
- Отсутствующий файл и изменённый режим
- Подвох: лишний файл остаётся незамеченным
- Как читать коды завершения
- Безопасная очистка учебного стенда
- Где эта проверка находится в приёмке бэкапа
- Границы результата
- Input conditions
- Preparing a secure staging environment
- First comparison: archive and directory match
- Changing one byte while keeping size and time unchanged
- Missing file and changed permissions
- The catch: an extra file goes unnoticed
- How to read exit codes
- Safe cleanup of the training environment
- Where this check fits into backup acceptance testing
- Result boundaries
tar --compare отвечает на узкий вопрос: совпадают ли участники архива с файлами в каталоге, из которого сделана копия. Команда не распаковывает архив поверх исходных данных. Код 0 означает, что различий среди участников архива не найдено; код 1 — что есть отличия; код 2 — что проверка завершилась с ошибкой.
Участник архива — запись внутри tar с путём и метаданными. Файловое соответствие — объект с тем же путём в выбранном каталоге. Это важно: команда начинает с состава архива, а не ищет всё, что лежит рядом на диске.
Сначала проверим границы. Сверка полезна сразу после создания архива, пока исходный каталог зафиксирован и ещё не очищен. Для работающего сайта результат быстро устаревает: приложение может изменить файл уже после снимка. Поэтому каталог источника должен быть неизменяемой подготовленной копией, снапшотом или остановленной на время тестовой моделью, а не живой директорией с записью.
Входные условия
Linux с GNU tar; проверка ниже выполнена на GNU tar 1.35.
Архив backup.tar и каталог-источник, относящиеся к одной точке времени.
Права чтения архива и всех сравниваемых файлов.
Изолированный временный каталог: команды примера не обращаются к рабочему сайту и сети.
tar --version
tar (GNU tar) 1.35
В тесте от 24 октября 2026 года использованы два коротких текстовых файла: site/index.html и db/catalog.sql. Это учебные данные, не копия клиента или рабочей базы.
Подготавливаем безопасный стенд
lab_dir="$(mktemp -d)"
printf '%s\n' "$lab_dir"
mkdir -p -- "$lab_dir/source/site" "$lab_dir/source/db"
printf '%s\n' 'version=A' > "$lab_dir/source/site/index.html"
printf '%s\n' 'rows=42' > "$lab_dir/source/db/catalog.sql"
find "$lab_dir/source" -type f -exec touch -d '2026-10-24 00:00:00 UTC' {} +
tar --create --file="$lab_dir/backup.tar" --directory="$lab_dir/source" .
Переменная lab_dir определяется первой командой. Все операции записи ниже ограничены созданным mktemp-каталогом. Дата файлов фиксируется только для воспроизводимости сравнения: она не является рекомендацией для рабочих копий.
Первое сравнение: архив и каталог совпадают
cp -a -- "$lab_dir/source" "$lab_dir/match"
tar --compare --file="$lab_dir/backup.tar" --directory="$lab_dir/match"
printf 'rc=%s\n' "$?"
rc=0
Пустой вывод вместе с кодом 0 означает, что GNU tar не нашёл различий среди участников backup.tar и их файловых соответствий в match. Один пустой вывод без сохранённого кода недостаточен: автоматизация должна проверять оба признака.
Изменение одного байта при прежнем размере и времени
cp -a -- "$lab_dir/source" "$lab_dir/changed"
printf 'B' | dd of="$lab_dir/changed/site/index.html" bs=1 seek=8 conv=notrunc status=none
touch -r "$lab_dir/source/site/index.html" "$lab_dir/changed/site/index.html"
tar --compare --file="$lab_dir/backup.tar" --directory="$lab_dir/changed"
./site/index.html: Contents differ
Команда завершилась с кодом 1. Размер и mtime файла были сохранены, но GNU tar прочитал содержимое и обнаружил замену A на B. Это полезное отличие от проверки только имени, размера и времени.
Отсутствующий файл и изменённый режим
Для сценария отсутствия файл не удаляется безвозвратно: он переносится за пределы сравниваемого каталога, но остаётся внутри временного стенда.
cp -a -- "$lab_dir/source" "$lab_dir/missing"
mv -- "$lab_dir/missing/db/catalog.sql" "$lab_dir/catalog.sql.off"
tar --compare --file="$lab_dir/backup.tar" --directory="$lab_dir/missing"
tar: ./db/catalog.sql: Warning: Cannot stat: No such file or directory
Результат — код 1: участник архива не найден в каталоге. В отдельном сценарии chmod 0600 для site/index.html при исходном 0644 дал сообщение Mode differs и тот же код 1. Следовательно, сравнение относится не только к содержимому, но и к метаданным, которые хранит архив.
Подвох: лишний файл остаётся незамеченным
cp -a -- "$lab_dir/source" "$lab_dir/extra"
printf '%s\n' 'not in archive' > "$lab_dir/extra/unlisted.txt"
tar --compare --file="$lab_dir/backup.tar" --directory="$lab_dir/extra"
printf 'rc=%s\n' "$?"
rc=0
tar идёт от участников архива к файловой системе. Поэтому unlisted.txt, которого нет в backup.tar, не входит в сравнение и не меняет код. Код 0 не доказывает, что архив содержит всё, что сейчас есть в каталоге. Полноту состава нужно проверять отдельно по ожидаемому перечню или снимку файлов.

Сценарий | Наблюдение | Код | Вывод |
|---|---|---|---|
Полное совпадение | вывод пуст | 0 | различия среди участников архива не найдены |
Один байт изменён | Contents differ | 1 | содержимое отличается |
Файл отсутствует | Cannot stat | 1 | участник архива не найден |
Режим 0644 → 0600 | Mode differs | 1 | метаданные отличаются |
В каталоге есть лишний файл | вывод пуст | 0 | лишний файл не входит в область проверки |

Как читать коды завершения
Официальное руководство GNU tar описывает --compare / --diff как сравнение участников архива с файловой системой и перечисляет проверяемые признаки. В разделе о кодах завершения код 1 означает найденные различия при --compare, а код 2 — фатальную ошибку.
Для отдельной проверки фатальной ошибки в том же временном стенде указан архив, которого не существует:
tar --compare --file="$lab_dir/no-such.tar" --directory="$lab_dir/match"
printf 'rc=%s\n' "$?"
rc=2
Код 2 здесь означает не найденное отличие файлов, а невозможность выполнить проверку: архив открыть нельзя. В автоматизации этот статус нужно отделять от RC 1.
Не объединяйте 1 и 2 в общий статус «архив испорчен». Код 1 может отражать ожидаемое изменение каталога после снимка. Код 2 означает, что сама операция проверки не завершилась штатно: например, архив недоступен или не читается.
Безопасная очистка учебного стенда
Сначала выведите путь и убедитесь, что он относится к временному каталогу. Очистка ниже разрешена только тогда, когда путь соответствует каталогу, который mktemp создал по заданному шаблону в TMPDIR или /tmp; при другом пути команда останавливается.
case "$lab_dir" in "${TMPDIR:-/tmp}"/tmp.*) rm -rf -- "$lab_dir" ;; *) printf 'cleanup stopped: %s\n' "$lab_dir" >&2 ;; esac
Где эта проверка находится в приёмке бэкапа
Сразу после создания архива зафиксируйте исходное дерево файлов или снапшот и версию GNU tar.
Выполните tar --compare и сохраните полный вывод вместе с кодом завершения.
При коде 1 разделите отличие содержимого, отсутствие файла и отличие метаданных; не делайте вывод о причине по одной строке вывода.
Отдельно сравните ожидаемый состав, потому что лишние файлы в исходном дереве команда не ищет.
После успешной сверки проверьте целостность переданного архива и выполните тестовое восстановление в изоляции.
Если исходного каталога уже нет, проверка tar.gz до распаковки отвечает на другой вопрос: читаются ли gzip-поток и структура tar. SHA-256-манифест помогает обнаружить изменение уже сохранённых файлов. Ни одна из этих проверок не заменяет восстановление приложения.
Границы результата
Сравнение не доказывает полноту архива относительно бизнес-требований.
Команда не подтверждает согласованность дампа работающей базы.
Лишний файл в каталоге, которого нет в архиве, не делает результат ненулевым.
Рабочий каталог с продолжающейся записью может дать различия, возникшие уже после создания копии.
Проверка не подтверждает подлинность архива и не заменяет защищённый манифест или подпись.
Результаты и формулировки относятся к GNU tar 1.35; в другой реализации и версии вывод может отличаться.
Критерий готовности: tar --compare завершился кодом 0 на каталоге той же точки времени, ожидаемый состав проверен отдельно, а вывод и версия инструмента сохранены. Только после этого имеет смысл переходить к проверке передачи и тестовому восстановлению.
tar --compare answers a narrow question: do the archive members match the files in the directory from which the copy was made? The command does not unpack the archive over the original data. Exit code 0 means no differences were found among archive members; code 1 means differences exist; code 2 means the check ended with an error.
An archive member is a record inside tar containing a path and metadata. File correspondence is an object with the same path in the selected directory. This is important: the command starts with the archive contents, not by searching for everything lying nearby on the disk.
First, let us check the boundaries. Verification is useful immediately after creating the archive while the source directory is still fixed and not yet cleaned. For a live site, the result quickly becomes outdated: the application may modify a file even after the snapshot. Therefore, the source directory must be an immutable prepared copy, a snapshot, or a stopped test model, not a live directory with active writes.
Input conditions
Linux with GNU tar; the check below was performed on GNU tar 1.35.
The backup.tar archive and the source directory, both corresponding to the same point in time.
Read permissions for the archive and all files being compared.
Isolated temporary directory: the example commands do not access the live site or the network.
tar --version
tar (GNU tar) 1.35
In the test from October 24, 2026, two short text files were used: site/index.html and db/catalog.sql. These are sample data, not a copy of a client or production database.
Preparing a secure staging environment
lab_dir="$(mktemp -d)"
printf '%s\n' "$lab_dir"
mkdir -p -- "$lab_dir/source/site" "$lab_dir/source/db"
printf '%s\n' 'version=A' > "$lab_dir/source/site/index.html"
printf '%s\n' 'rows=42' > "$lab_dir/source/db/catalog.sql"
find "$lab_dir/source" -type f -exec touch -d '2026-10-24 00:00:00 UTC' {} +
tar --create --file="$lab_dir/backup.tar" --directory="$lab_dir/source" .
The lab_dir variable is defined by the first command. All subsequent write operations are limited to the mktemp directory created. File dates are recorded solely for reproducibility of the comparison; they are not a recommendation for production copies.
First comparison: archive and directory match
cp -a -- "$lab_dir/source" "$lab_dir/match"
tar --compare --file="$lab_dir/backup.tar" --directory="$lab_dir/match"
printf 'rc=%s\n' "$?"
rc=0
Empty output with exit code 0 means GNU tar found no differences between the contents of backup.tar and their corresponding files in match. Empty output without a saved exit code is insufficient: automation must verify both conditions.
Changing one byte while keeping size and time unchanged
cp -a -- "$lab_dir/source" "$lab_dir/changed"
printf 'B' | dd of="$lab_dir/changed/site/index.html" bs=1 seek=8 conv=notrunc status=none
touch -r "$lab_dir/source/site/index.html" "$lab_dir/changed/site/index.html"
tar --compare --file="$lab_dir/backup.tar" --directory="$lab_dir/changed"
./site/index.html: Contents differ
The command exited with code 1. The file size and mtime were preserved, but GNU tar read the content and detected a replacement of A with B. This is a useful distinction from checking only name, size, and time.
Missing file and changed permissions
For the missing-file scenario, the file is not permanently deleted: it is moved outside the compared directory but remains within the temporary staging environment.
cp -a -- "$lab_dir/source" "$lab_dir/missing"
mv -- "$lab_dir/missing/db/catalog.sql" "$lab_dir/catalog.sql.off"
tar --compare --file="$lab_dir/backup.tar" --directory="$lab_dir/missing"
tar: ./db/catalog.sql: Warning: Cannot stat: No such file or directory
Result: code 1 — archive member not found in the directory. In a separate scenario, chmod 0600 for site/index.html with an initial 0644 produced the "Mode differs" message and the same code 1. Therefore, the comparison covers not only content but also metadata stored in the archive.
The catch: an extra file goes unnoticed
cp -a -- "$lab_dir/source" "$lab_dir/extra"
printf '%s\n' 'not in archive' > "$lab_dir/extra/unlisted.txt"
tar --compare --file="$lab_dir/backup.tar" --directory="$lab_dir/extra"
printf 'rc=%s\n' "$?"
rc=0
tar proceeds from archive members to the file system. Therefore, unlisted.txt, which is not in backup.tar, is not included in the comparison and does not change the code. Code 0 does not prove that the archive contains everything currently in the directory. Completeness of the contents must be checked separately against an expected list or file snapshot.

Script | Observation | Code | Output |
|---|---|---|---|
Exact match | output is empty | 0 | no differences among archive members found |
One byte changed | Contents differ | 1 | contents differ |
File not found | Cannot stat | 1 | archive member not found |
Mode 0644 → 0600 | Mode differs | 1 | metadata differs |
An extra file exists in the catalog | the output is empty | 0 | the extra file is outside the verification scope |

How to read exit codes
The official GNU tar manual describes --compare / --diff as comparing archive members with the file system and lists the attributes checked. In the section on exit codes, code 1 indicates found differences with --compare, and code 2 indicates a fatal error.
For a separate check of a fatal error in the same staging environment, an archive that does not exist is specified:
tar --compare --file="$lab_dir/no-such.tar" --directory="$lab_dir/match"
printf 'rc=%s\n' "$?"
rc=2
Code 2 here does not mean a missing file difference, but the inability to perform the check: the archive cannot be opened. In automation, this status must be distinguished from RC 1.
Do not merge 1 and 2 into a single status of 'corrupted archive'. Code 1 may reflect an expected change in the directory after the snapshot. Code 2 means the check operation itself did not complete normally: for example, the archive is unavailable or unreadable.
Safe cleanup of the training environment
First, output the path and verify it refers to a temporary directory. The cleanup below is allowed only if the path matches a directory created by mktemp based on a template in TMPDIR or /tmp; for any other path, the command stops.
case "$lab_dir" in "${TMPDIR:-/tmp}"/tmp.*) rm -rf -- "$lab_dir" ;; *) printf 'cleanup stopped: %s\n' "$lab_dir" >&2 ;; esac
Where this check fits into backup acceptance testing
Immediately after creating the archive, record the original file tree or snapshot and the GNU tar version.
Run tar --compare and save the full output along with the exit code.
For exit code 1, distinguish between content differences, missing files, and metadata differences; do not infer the cause from a single line of output.
Separately compare the expected composition, as the command does not search for extra files in the source tree.
After a successful comparison, verify the integrity of the submitted archive and perform a test restoration in isolation.
If the source directory no longer exists, tar.gz pre-extraction check addresses a different question: can the gzip stream and tar structure be read? SHA-256 manifest helps detect changes to already saved files. Neither of these checks replaces application restoration.
Result boundaries
Comparison does not prove archive completeness relative to business requirements.
The command does not confirm the consistency of a dump from a running database.
An extra file in a directory that is not in the archive does not make the result non-zero.
A working directory with ongoing writes may produce differences that arose after the copy was created.
The check does not confirm the archive's authenticity and does not replace a protected manifest or signature.
Results and wording apply to GNU tar 1.35; output may differ in another implementation or version.
Readiness criterion: tar --compare completed with code 0 on the directory of the same point in time, the expected composition was verified separately, and the output and tool version were saved. Only after this is it meaningful to proceed to transfer verification and test restoration.





Обсуждение 0
Делись опытом и задавай вопросы. Комментарии без ссылок появляются после проверки редактором.
Пока никто не написал. Начни обсуждение.