Определите, какие загрузки нужно исправить

ShellBeginner
Практиковаться сейчас

Введение

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.

Download Desk со ссылками на фактические локальные материалы

Используйте 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, сохраняя строки целиком. Вы различили отсутствующие файлы, неверные байты и допустимые пустые файлы, не меняя исходный пакет. Теперь ведомость даёт основание для каждого последующего исправления.