Публикация только полного отчёта о продажах

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

Введение

DAYMARK — небольшое кафе. При закрытии команда скачивает CSV продаж для учётной книги. Ошибка расчёта не должна заменять последний полный файл. Сначала вы разберётесь в суммах, затем завершите короткий публикующий Bash-скрипт; программа расчёта предоставлена.

Достаточно базового знакомства с терминалом. Команды и синтаксис shell объясняются перед использованием. Начните в Daymark, настоящем сайте на порту 8081; команды выполняйте в Workstation, подготовленном в /srv/daymark-sales. Данные вымышленные, установка и внешняя учётная запись не нужны.

Понимание и расчёт итогов закрытия

На этом шаге вы сравните исходные заказы кафе с настоящим кандидатом на экспорт. Начните в Daymark. Откройте View source records ↗. Четыре исходные строки описывают 6 Espresso по 300 центов, 3 Tea по 250 и 2 Cake по 450: всего 11 единиц и 3450 центов. Цент — сотая часть денежной единицы; целые центы исключают неоднозначность округления. Повторяющиеся строки товара нужно объединить.

Четыре исходные строки и цены за единицу

Откройте Reports и Download latest CSV ↓. Будет сохранён настоящий CSV-файл. CSV означает значения, разделённые запятыми; первая строка задаёт имена столбцов. Начальный файл относится к предыдущему закрытию и содержит TOTAL,1,100. Он должен оставаться доступным до появления полной замены. Вернитесь на главную через DAYMARK.

Перейдите в Workstation. pwd выводит рабочий каталог, ls перечисляет файлы, а cat выводит текстовый файл. Относительный путь разрешается от текущего каталога.

pwd

Ожидается /srv/daymark-sales.

ls
cat orders.csv

Строки совпадают с сайтом. python3 запускает предоставленный калькулятор. Его абсолютный путь работает независимо от текущего каталога. > направляет стандартный вывод в файл, заменяя этот файл ещё до запуска программы. Используйте отдельный кандидат, а не опубликованный отчёт:

/usr/bin/python3 /opt/labex/d10/summarize.py orders.csv > candidate.csv
cat candidate.csv
item,quantity,value_cents
Cake,2,900
Espresso,6,1800
Tea,3,750
TOTAL,11,3450

Источник содержит цену единицы, а отчёт — объединённое количество и общую стоимость. Нулевой статус завершения означает успех, ненулевой — ошибку. $? раскрывается в статус предыдущей команды, поэтому читайте его сразу после интересующей команды. echo выводит текст:

/usr/bin/python3 /opt/labex/d10/summarize.py fixtures/broken.csv > rejected.csv
echo $?

Ожидаются Export failed: ... и 1. Это намеренно. cat rejected.csv показал бы заголовок даже при ошибке расчёта: частичный вывод не является правильным отчётом. Существующий файл для скачивания по-прежнему содержит TOTAL,1,100, поскольку вы писали лишь отдельные кандидаты. Если путь не работает, проверьте pwd и ls, вернитесь командой cd /srv/daymark-sales и повторите создание кандидата. cd меняет каталог. Сохраните исходные заказы и существующий отчёт.

Публикация только после успеха

На этом шаге вы замените небезопасный скрипт и продемонстрируете как сохранение файла, так и восстановление с новыми данными. Начните в Workstation. Скрипт принимает два аргумента: входной CSV и путь публикации. Прочитайте его:

cat publish.sh

Прямой > может обрезать опубликованный файл ещё до окончания неудачного расчёта. Вместо этого создайте временный файл рядом с назначением, успешно запишите его и затем переименуйте. В одной файловой системе переименование атомарно заменяет видимое имя: читатели видят либо полные старые байты, либо полные новые. Это не обеспечивает транзакций базы данных или защиты от потери диска.

Небольшой скрипт выполняется в Bash. set -e останавливается при ошибке обычной команды; -u отвергает неустановленные переменные. $1 и $2 — два аргумента. name=value присваивает переменную shell без пробелов около =; $(command) захватывает вывод команды. Кавычки сохраняют пробелы в путях. mktemp создаёт уникальный файл по суффиксу XXXXXX. trap ... EXIT удаляет остатки временных данных и после успеха, и после ошибки. chmod 644 разрешает владельцу запись, а всем чтение. mv -fT заменяет точное имя назначения; -T отвергает каталог назначения вместо перемещения файла внутрь. printf выводит сведения о публикации; id -u — реальный числовой идентификатор пользователя, а sha256sum идентифицирует байты файла.

cat > publish.sh заменяет только ваш скрипт. Заключённый в кавычки SH начинает here-document: вставьте всё до последнего SH на отдельной строке. Кавычки сохраняют знаки доллара буквально.

cat > publish.sh <<'SH'
#!/bin/bash
set -eu
input=$1
output=$2
tmp=$(mktemp "${output}.XXXXXX")
trap 'rm -f "$tmp"' EXIT
/usr/bin/python3 /opt/labex/d10/summarize.py "$input" > "$tmp"
chmod 644 "$tmp"
mv -fT "$tmp" "$output"
printf 'Published %s uid=%s cwd=%s sha256=' "$output" "$(id -u)" "$PWD"
sha256sum "$output"
SH

Подготовленная учётная запись daymark-report владеет reports/; она может писать отчёты, а сайт только читает их. sudo -u запускает от имени этой записи. /bin/bash — абсолютный путь; при явной передаче Bash скрипту не требуется разрешение на исполнение.

sudo -u daymark-report /bin/bash /srv/daymark-sales/publish.sh orders.csv /srv/daymark-sales/reports/sales.csv
cat reports/sales.csv

Ожидается полный отчёт с TOTAL,11,3450. cp копирует файл; перезаписывайте только orders.csv этого упражнения. Сохраните исходный набор-пример. Затем намеренно передайте некорректные данные:

cp fixtures/broken.csv orders.csv
sudo -u daymark-report /bin/bash /srv/daymark-sales/publish.sh orders.csv /srv/daymark-sales/reports/sales.csv
echo $?

Ожидаются намеренная ошибка и 1. Перейдите в Daymark, обновите Reports, скачайте файл снова и убедитесь, что TOTAL,11,3450 сохранилось. Неудачная попытка не должна ни публиковать один заголовок, ни удалять предыдущий файл.

Вернитесь в Workstation. Восстановите работу с новым правильным закрытием, в котором на два Tea больше. Оно должно дать 13 единиц и 3950 центов, а не вечно оставлять старый отчёт:

cp fixtures/next.csv orders.csv
sudo -u daymark-report /bin/bash /srv/daymark-sales/publish.sh orders.csv /srv/daymark-sales/reports/sales.csv
cat reports/sales.csv

Ожидаются Tea,5,1250 и TOTAL,13,3950. В Daymark обновите Records и Reports и скачайте файл снова: источник и отчёт теперь согласованы. При отказе в доступе проверьте точный путь вывода и повторите sudo -u daymark-report; не разрешайте запись всем. Если в скрипте опечатка, замените его полным here-document и повторите попытку. Временный файл создаётся рядом с выходным, чтобы окончательное переименование оставалось в одной файловой системе.

Резюме

Вы потренировали публикацию полного CSV, осмысленный статус ошибки и восстановление. Отчёт по расписанию полезен лишь тогда, когда реальный исполнитель, срабатывание и бизнес-суммы согласованы. Это упражнение на одном экземпляре использует вымышленные данные и короткое учебное расписание, а не полноценную производственную систему отчётности.