Введение
Field Notes готовит общественное мероприятие на выходные. В пакет материалов входят PDF-путеводитель, раздаточные материалы и необязательный файл благодарностей, который может быть пустым. Имя файла и правдоподобный размер ещё не доказывают полноту загрузки. Прежде чем что-либо скачивать, вы составите ведомость, которая точно покажет организаторам, какие файлы требуют внимания.
Предполагается знание базовых аргументов Bash, условий и циклов из Shell for Beginners. В этой работе объясняются SHA256, чтение целых строк и используемая классификация. Инструменты и оригинальные синтетические материалы подготовлены. Workspace и Download Desk используют один контейнер; эта работа начинается независимо. Оценка времени включает чтение и исправление обычных опечаток.
Составьте обоснованную ведомость
На этом шаге вы превратите доверенный контрольный список в ведомость фактического локального пакета, не исправляя и не перезаписывая его файлы.
Сначала откройте полезный файл
Начните в Workspace, подготовленном для текста UTF-8. Рабочий каталог — /home/labex/project/download-desk. pwd показывает текущий каталог. Если относительный путь не найден, проверьте его с помощью ls и вернитесь сюда полной командой cd ниже.
cd /home/labex/project/download-desk
ls pack
Переключитесь на Download Desk. Выберите Open file рядом с Welcome guide.pdf. На новой странице браузера должны появиться программа мероприятия и место встречи у восточного входа. При необходимости используйте масштабирование PDF-просмотрщика: PDF состоит из фиксированных страниц, а не из текста, перестраиваемого для мобильного экрана. Вернитесь на страницу Download Desk и выберите Download рядом с файлом, чтобы сохранить те же локальные байты. Затем вернитесь в Workspace.

Используйте Open file или Download рядом с Welcome guide.pdf.
Просмотрщик отдаёт только реальные файлы из pack. Он не может восполнить отсутствующий файл из источника. Текстовый материал может отобразиться как текст, а необязательный пустой файл — как пустая страница. Сами эти наблюдения ещё не подтверждают правильность содержимого.
Используйте независимый эталон
Организаторы предоставили /opt/labex/download-pack-state/expected.sha256 отдельно от доступного для записи пакета. Хеш SHA256 — это 64-символьный отпечаток байтов файла. Сравнение с независимым доверенным значением выявляет различия байтов, в том числе повреждения без изменения размера. Оно не удостоверяет личность издателя: если злоумышленник предоставил и файл, и контрольную сумму, их совпадение не делает издателя заслуживающим доверия. Не создавайте эталон заново из проверяемых файлов.
cat показывает файл, не изменяя его:
cat /opt/labex/download-pack-state/expected.sha256
Каждая строка содержит 64-значный шестнадцатеричный хеш в нижнем регистре, два пробела и полное имя файла. В курсе используется предоставленный читаемый непустой манифест именно в этом формате, с завершающим переводом строки. Имена не содержат уровней каталогов, состоят из печатных символов ASCII и могут включать пробелы. Косая черта, обратная косая черта, CR, LF, табуляция и имена . и .. не входят в область поддержки. Пакет и вся цепочка его каталогов — настоящие каталоги; перечисленные элементы являются обычными локальными файлами либо отсутствуют. Связанные ссылками файлы, подкаталоги на месте ожидаемого файла и произвольные форматы контрольных сумм с экранированием не поддерживаются. В этой диагностической работе оставьте все исходные файлы пакета и notes.txt без изменений.
sha256sum выводит хеш и имя файла. Двойные кавычки сохраняют имя с пробелами как один аргумент. -- завершает параметры команды. Префикс каталога также не даёт принять базовое имя, начинающееся с -, за параметр.
sha256sum -- "pack/Workshop card.txt"
Сравните этот хеш со строкой эталона. Они различаются. В повреждённом файле столько же байтов, сколько в правильном раздаточном материале, поэтому размер не выявил бы проблему.
sha256sum --check читает манифест и проверяет его пути относительно текущего каталога. Круглые скобки запускают команды в подоболочке: её cd не меняет каталог внешнего терминала.
(cd pack && sha256sum --check /opt/labex/download-pack-state/expected.sha256)
Здесь && запускает проверку только после успешного перехода в pack. Вы должны увидеть Welcome guide.pdf: OK, Workshop card.txt: FAILED, Map notes.txt: FAILED open or read и Optional credits.txt: OK, а также предупреждения. Из-за отсутствующего файла и неверных байтов эта команда намеренно завершается неуспешно. $? содержит собственный код завершения предыдущей команды; прочитайте его немедленно, пока другая команда не заменила значение. printf форматирует значение, а \n завершает строку.
printf 'Check exit: %s\n' "$?"
Ожидается Check exit: 1. Нулевой по размеру файл благодарностей допустим, поскольку его хеш совпадает. Требование «непустой» относится к манифесту, а не к каждому материалу. Одна строка OK не означает, что весь пакет исправен.
Сохраняйте имена при чтении строк
Организаторам нужна компактная ведомость: статус и полное имя файла в каждой строке, в порядке манифеста. Вы создадите inventory.sh, получающий манифест как $1, а каталог пакета как $2. Это самостоятельная программа, использующая эти аргументы и установленные команды, без соседних вспомогательных файлов.
Перед записью разберите синтаксис оболочки:
while IFS= read -r lineчитает целую строку на каждой итерации. ПустойIFSпредотвращает удаление пробелов;-rотключает интерпретацию обратной косой черты.done < "$manifest"направляет манифест в цикл вместо запроса ввода из терминала.${line:0:64}извлекает хеш из позиций 0–63.${line:66}извлекает всё после двух разделяющих пробелов. Имя файла не разбивается на слова.[ -f "$target" ]проверяет, что поддерживаемый объект является обычным файлом. Отсутствующий элемент классифицируется до команды вычисления контрольной суммы.actual=$(sha256sum -- "$target")захватывает вывод команды.${actual%% *}удаляет самый длинный подходящий суффикс из пробела и любого следующего текста, оставляя хеш. Это безопасно для описанного выше ограниченного формата имён.printf '%s\t%s\n'выводит два значения с табуляцией между ними и переводом строки в конце. Кавычки сохраняют каждое полное имя как один аргумент.
Следующий here-document сохраняет в скрипт буквальный текст. cat > inventory.sh заменяет этот файл скрипта; <<'BASH' заканчивается строкой, содержащей только BASH. Кавычки вокруг разделителя не дают текущей оболочке раскрыть переменные скрипта при сохранении. Первая строка указывает Bash; здесь мы явно запускаем файл через bash.
cat > inventory.sh <<'BASH'
#!/usr/bin/env bash
manifest=$1
pack=$2
while IFS= read -r line; do
expected=${line:0:64}
name=${line:66}
target=$pack/$name
status=MISSING
if [ -f "$target" ]; then
actual=$(sha256sum -- "$target")
actual=${actual%% *}
status=MISMATCH
if [ "$actual" = "$expected" ]; then
status=MATCH
fi
fi
printf '%s\t%s\n' "$status" "$name"
done < "$manifest"
BASH
Запустите скрипт с предоставленным эталоном и локальным пакетом. > направляет его стандартный вывод в inventory.tsv, заменяя отчёт при каждом запуске. TSV означает значения, разделённые табуляцией. Этот отчёт — диагностический результат для организаторов, он не исправляет материалы.
bash inventory.sh /opt/labex/download-pack-state/expected.sha256 pack > inventory.tsv
cat inventory.tsv
Ожидаются следующие строки с одной табуляцией между статусом и именем:
MATCH Welcome guide.pdf
MISMATCH Workshop card.txt
MISSING Map notes.txt
MATCH Optional credits.txt
Скрипт может завершиться с кодом ноль, даже если отчёт содержит MISSING: его задача — классифицировать, а не утверждать, что пакет полон. Правильность отчёта определяется его связью с реальными файлами и доверенным эталоном. Проверка также испытает ваш скрипт на другом пакете с другими именами и пустым файлом; именно такая запись цикла не обязательна.
Если вы ошиблись в строке скрипта, повторите here-document целиком, заменив только inventory.sh, и заново создайте отчёт. Если случайно работаете из pack, вернитесь абсолютной командой cd выше. Не меняйте pack, доверенный эталон и notes.txt. Повторный запуск должен дать тот же отчёт, поскольку он лишь читает пакет. В следующей работе вы будете решать, что загружать, на основе этих категорий.
Резюме
Вы открыли настоящий материал, сравнили пакет с независимым эталоном SHA256 и создали ведомость с помощью Bash, сохраняя строки целиком. Вы различили отсутствующие файлы, неверные байты и допустимые пустые файлы, не меняя исходный пакет. Теперь ведомость даёт основание для каждого последующего исправления.



