Скрипт керує bea за чотирма рішеннями: який журнал він читає, --json для машинно-зрозумілого виводу, jq для потрібного значення та код виходу, за яким відбувається гілкування. Цей посібник проходить ці чотири рішення від початку до кінця, а потім розкладає їх за розкладом.
Вам потрібен bea на машині, що виконує завдання, і журнал, до якого він має доступ. Якщо ви починаєте нові книги, спочатку дотримуйтесь швидкого старту CLI. Кожен факт про прапори, ключі конвертів і коди виходу шукається у довіднику Beancount CLI, тут не повторюється.
Виберіть журнал явно
Назвіть файл. Локальна команда розв’язує свій цільовий шлях через --file, потім $BEA_FILE, потім ./main.bean у робочій директорії, а заплановане завдання рідко виконується там, де ви думаєте.
bea --file ~/books/main.bean check
BEA_FILE=~/books/main.bean bea check
cd ~/books && bea checkГлобальні опції йдуть перед командою, як у bea --file main.bean check. Якщо розв’язаний файл не існує, команда завершується з 2 і перераховує всі три джерела, тож помилка в записі cron викликає гучний збій замість перевірки неправильних книг. Веб-хостинговий таргетинг через прапор --ledger ще не існує; bea ніколи не завантажує локальний файл неявно.
Читайте JSON-конверт
Додайте глобальний --json, і кожна підтримувана команда відповідає тим самим конвертом: bea, target, data, truncated і limit у межових списках. Суми — це рядки з десятковими числами, а дати — ISO YYYY-MM-DD, тож значення безпечне для порівняння без жодних чисел із плаваючою комою у конвеєрі. Ключі конверта наведені в довіднику JSON і кодів виходу.
bea --json --file main.bean report income-statement | jq .data.net_profit
bea --json --file main.bean list transaction --limit 2 | jq '.data[0].postings[0].units'
bea --json --file main.bean import statement.csv --csv date=Date,amount=Amount,payee=Payee \
--account Assets:Checking --apply --duplicates skip | jq '.data | {written, ready, duplicates}'Ці три команди — report, list і import — зберігають форми своїх результатів, тож шлях jq, написаний під них, залишається дійсним. bea --json check і bea --json query також сьогодні видають конверт, але вони — команди, що передаються рідним виконуваним файлам Beancount, тому скрипт має орієнтуватися на код виходу check, а не на форму виводу. Вибирайте політику дублювання свідомо: --duplicates все ще потрібен, коли імпорт потребує рішення, як пояснює інструкція з імпорту.
Зупиняйтеся на правильному коді виходу
Розгалужуйтеся за статусом і читайте об’єкт помилки перед повторною спробою чогось, що записує. У режимі --json збій не пише нічого в stdout і саме один об’єкт у stderr, чиї error.category імена класу: validation (1), usage (2), auth (3), conflict (4).
#!/usr/bin/env bash
set -euo pipefail
out=$(mktemp)
err=$(mktemp)
status=0
bea --json --file main.bean report income-statement >"$out" 2>"$err" || status=$?
case "$status" in
0) jq -r '.data.net_profit | to_entries[] | "net profit: \(.value) \(.key)"' "$out" ;;
4) echo "conflict — inspect the ledger before retrying" >&2
jq -r '.error.message' "$err" >&2
exit 4 ;;
*) jq -r '.error | "\(.category) (exit \(.exit_code)): \(.message)"' "$err" >&2
exit "$status" ;;
esacВихід 4 — це той, який скрипт ніколи не повинен повторювати бездумно: він означає, що результат конфліктний або невідомий, наприклад, зовнішнє редагування під час запису або ціль init, яка вже існує. Перевірте книгу обліку, потім спробуйте знову почати з нового зчитування. Вихід 1 охоплює помилки валідації та будь-які інші помилки під час виконання; error.details містить окремі помилки книги обліку, а error.result — те, що фактично зробив частковий запис. Ненульовий вихід ніколи не гарантує, що нічого не змінилося.
Запуск без термінала
bea припиняє запити самостійно. --no-input є передбаченим, коли stdin не є терміналом, коли встановлено --json, і коли CI істинний — 1, true, yes або on. У цьому режимі відсутність підтвердження призводить до невдачі з виходом 2 замість нескінченного очікування.
CI=true BEA_NO_UPDATE_NOTIFIER=1 bea --json --file main.bean report balance-sheet
bea --json --file main.bean list transaction --limit 100 --sort oldestЗчитування є ліберальним у терміналі і суворим у всіх інших випадках. Коли у книзі обліку є помилки завантаження, query, list і report виходять із кодом 1 під --json, під конвеєром stdout, під істинним CI або з --strict; передайте власний --allow-errors команди, щоб прийняти часткову відповідь, що також встановлює ledger_valid: false і заповнює ledger_errors у JSON. --strict — це дзеркальна ситуація: він відмовляється від часткових відповідей навіть у терміналі, що саме й потрібно, коли скрипт виконується вручну людиною. bea check не має --allow-errors — звітування про помилки є його основним завданням — і завжди виходить із 1 при виявленні помилок. Встановіть BEA_NO_UPDATE_NOTIFIER=1, щоб вимкнути пасивне сповіщення про оновлення; істинний CI уже це робить.
Запланувати перевірку
Запускайте валідацію щоночі і нехай код виходу буде сигналом тривоги. Обидва блоки нижче є шаблонами — шляхи, розклад і виконавець — ваші.
# crontab -e — 07:15 daily; cron mails you only when bea exits nonzero
15 7 * * * BEA_NO_UPDATE_NOTIFIER=1 /opt/homebrew/bin/bea --file /home/alice/books/main.bean checkname: ledger
on:
schedule:
- cron: "15 7 * * *"
push:
jobs:
check:
runs-on: ubuntu-latest
env:
BEA_NO_UPDATE_NOTIFIER: "1"
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- run: uv tool install beancount-io==0.2.0
- run: bea --file main.bean check
- run: bea --json --file main.bean report balance-sheet > balance-sheet.jsonПерша команда на основі механізму завантажує керований механізм, тому виконавець потребує доступу до мережі. Щоб повторно використовувати його в різних завданнях, кешуйте ~/.local/share/bea/engine з ключем, що містить ОС виконавця, архітектуру, версію Python та зафіксовану версію bea. Фіксуйте версію, коли завдання повинно бути відтвореним, і знімайте фіксацію, коли бажаєте слідкувати за релізами. CI вже істинний у GitHub Actions, тому підказки вимкнені, а сповіщення про оновлення — мовчазне, поки ви нічого не встановите. Тут спеціально немає кроку форматування. Заплановане завдання не повинно переписувати файли без потреби, тому використовуйте bea format main.bean --check у хуку pre-commit, який нічого не змінює і виходить з 1, якщо файл потребує форматування.
Використання розміщеної облікової інформації в завданні
Встановіть BEA_TOKEN, взятий зі сховища секретів вашого CI провайдера, і повністю обійдіть вхід через браузер. Токен зчитується з оточення і ніколи не записується на диск, тому нічого не потрапляє до домашнього каталогу виконавця, щоб наступна задача могла це знайти.
export BEA_TOKEN="$YOUR_CI_SECRET"
bea --json cloud statusВихід 0 означає, що облікові дані розпізнані, а конверт вказує акаунт, до якого вони належать; вихід 3 з error.category від auth означає, що ні, а повідомлення розрізняє не задані облікові дані та відхилені. bea cloud logout нічого не робить з токеном, переданим таким чином — він його не відкликає і не скасовує, оскільки інша задача може ним користуватися — тому відкличте витіклий токен через панель керування. Локальні команди зовсім не потребують облікових даних; лише bea cloud і bea ask звертаються до розміщеного сервісу. Повний список змінних наведено у довідці налаштувань.
Не все відповідає у форматі JSON. bea ask категорично відхиляє режим JSON, bea cloud login потребує людини, а успішний bea cloud logout чи bea cloud ledger clone не повертає жодного об’єкта успіху в JSON — натомість читайте їхній статус виходу. Вивід допомоги, версії та автозаповнення оболонки залишається текстовим.
Наступні кроки
- Автоматизуйте банківські файли за допомогою покрокового імпорту через CLI.
- Шукайте будь-які прапорці, ключі конвертів або коди виходу у довідці Beancount CLI.
- Звертайтеся до Python лише коли CLI вичерпає можливості: дивіться скриптовані робочі процеси.