十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Actual Budget CLI 完全指南:用 @actual-app/cli 在终端管理与查询预算数据

Actual Budget CLI 完全指南:用 @actual-app/cli 在终端管理与查询预算数据 Actual Budget CLI 完全指南用 actual-app/cli 在终端管理与查询预算数据【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actual本篇技术指南系统讲解 Actual Budget 官方命令行工具actual-app/cli的使用与原理。该 CLI 面向个人财务管理场景通过连接 Actual sync server让你可以在终端直接查询和修改预算、账户、交易、类别、收款方payee、规则、日程等全部核心数据。读完本文你将掌握 CLI 的安装、三层配置方式环境变量 / CLI 标志 / 配置文件、全部命令与参数、ActualQL 查询能力、金额与输出格式约定并能结合源码理解其连接、缓存与锁机制的底层行为轻松写出可复用的财务自动化脚本。CLI 与 Server CLI 的定位区别在开始之前先明确一个容易混淆的点本文讲解的actual-app/cli是数据操作客户端它连接并操作一个已经运行的 Actual 服务而 Server CLIactual-app/sync-server 是服务端管理工具用于托管和管理 Actual 服务器本身如启动服务、管理账户。两者职责完全不同前者面向用数据后者面向开服务。从源码看actual-app/cli的核心依赖是actual-app/api见 packages/cli/package.json即官方 JS API 的封装层说明所有命令最终都是通过 API 与服务器通信。安装与要求环境要求Node.js v22 或更高版本package.json中engines.node声明为22。安装方式作为项目依赖安装npm install --save actual-app/cli或全局安装npm install --locationglobal actual-app/cli安装后npm 会同时暴露两个可执行命令见 packages/cli/package.json 的bin字段actual与actual-cli二者指向同一入口dist/cli.js。全局安装后即可直接使用actual命令。配置三种来源与优先级CLI 需要连接一个运行中的 Actual sync server。配置可以通过环境变量、CLI 全局标志和配置文件三种途径提供。从 resolveConfig 实现 可以看出三者优先级为CLI 标志 环境变量 配置文件 默认值。环境变量变量说明ACTUAL_SERVER_URLActual sync server 的 URL必需ACTUAL_SYNC_ID预算的 Sync ID大多数命令必需ACTUAL_PASSWORD服务器密码密码与会话令牌二选一ACTUAL_SESSION_TOKEN会话令牌密码的替代方案除上述文档列出的变量外从 index.ts 的全局选项定义 还可确认以下扩展环境变量ACTUAL_DATA_DIR本地数据目录、ACTUAL_ENCRYPTION_PASSWORD端到端加密预算的加密密码、ACTUAL_CACHE_TTL缓存有效期秒数默认 60、ACTUAL_LOCK_TIMEOUT锁等待秒数默认 10、ACTUAL_NO_LOCK禁用预算目录锁。CLI 全局标志全局标志可以覆盖环境变量放在命令之前标志说明--server-url url服务器 URL--password pw服务器密码--session-token token会话令牌--sync-id id预算 Sync ID--data-dir path本地缓存预算数据的目录--format format输出格式json默认、table、csv--verbose在 stderr 输出信息性消息此外源码还提供--encryption-password pw、--cache-ttl seconds非负整数、--refresh强制本次调用同步并忽略缓存、--no-cache--refresh的别名、--lock-timeout seconds默认 10、--no-lock禁用预算目录锁谨慎使用。--format通过 commander 的.choices()限定只能取json、table、csv三者之一传其他值会直接报错。配置文件配置文件由 cosmiconfig采用searchStrategy: global即从当前工作目录向上逐级搜索直到主目录。支持的文件名/位置如下.actualrcJSON 或 YAML.actualrc.json、.actualrc.yaml、.actualrc.ymlactual.config.json、actual.config.yaml、actual.config.ymlpackage.json中的actual键也可以把配置放在全局配置目录下的actual子目录中Linux 上如~/.config/actual/支持configJSON 或 YAMLconfig.json、config.yaml、config.yml示例.actualrc.json{ serverUrl: http://localhost:5006, password: your-password, syncId: 1cfdbb80-6274-49bf-b0c2-737235a4c81f, cacheTtl: 60, lockTimeout: 10, noLock: false }配置文件的合法键由源码严格校验validateConfigFileContent字符串键为serverUrl、password、sessionToken、syncId、dataDir、encryptionPassword非负整数键为cacheTtl、lockTimeout布尔键为noLock。出现未知键或类型不符都会抛出Invalid config file: ...错误。当serverUrl缺失时CLI 会直接报错Server URL is required...当password与sessionToken同时缺失时报错Authentication required...——这两个校验都在 resolveConfig 中完成。安全提示不要在配置文件中保存明文密码。如果文件确实包含密码在 Linux 上设置严格权限如 600如果文件位于 git 仓库中务必加入.gitignore。优先使用ACTUAL_PASSWORD/ACTUAL_SESSION_TOKEN环境变量或在配置中使用会话令牌session token而非密码。运行模型每次调用背后的完整流程理解 CLI 的每次执行都经历了什么有助于写出高效的自动化脚本。核心逻辑集中在 withConnection解析配置按 CLI 标志 环境变量 配置文件 默认值合并出完整配置。初始化 API调用api.init()传入serverURL、dataDir及password或sessionToken见 connection.ts。获取预算skipBudget为 false 时根据 Sync ID 走三条路径之一由 decideSyncAction 决策download首次使用或缓存状态缺失/与 syncId、serverUrl 不匹配时调用api.downloadBudget()全量下载预算并把state.json写入{dataDir}/.actual-cli/{syncId}/skip缓存未过期距上次同步小于cacheTtl秒且是只读命令时直接loadBudget()使用本地缓存不访问服务器同步sync缓存过期、或命令会修改数据mutates: true、或传了--refresh、或 TTL 为 0、或预算是加密的此时loadBudget()后调用api.sync()从服务器拉取最新变更。执行命令回调。推送变更若命令会修改数据mutates: true执行后再次api.sync()把本地改动推送到服务器并更新缓存状态。关闭连接无论成功失败最终都会调用api.shutdown()。预算目录锁防止并发写冲突由于 CLI 在本地维护一份预算缓存多个 CLI 进程并发读写同一份数据可能导致损坏。CLI 使用proper-lockfile实现了读写锁见 lock.ts读命令mutates: false获取共享锁acquireShared多个只读进程可同时运行写命令mutates: true获取排他锁acquireExclusive必须等待所有读者离开同时阻止其他进程进入锁等待超时默认 10 秒可用--lock-timeout调整后仍未获取会报错Another CLI process is holding the budget (waited Ns). Retry, or use a different --data-dir.锁实现还会通过 PID 检查清扫崩溃进程残留的过期读者标记sweepStaleReadersstale: 30_000处理僵死锁。如果你明确知道没有其他进程在操作同一份缓存可以用--no-lock跳过加锁换取更快的启动。数据目录与缓存默认数据目录为~/.actual-cli/data见 config.ts每个预算的缓存状态存放在{dataDir}/.actual-cli/{syncId}/state.json。缓存写入是尽力而为的即使目录不可写CLI 也不会崩溃只是下次重新下载cache.ts 的 writeCacheState。缓存的元数据包含版本、syncId、budgetId、serverUrl、lastSyncedAt与lastDownloadedAt其中serverUrl参与缓存判定——换服务器会自动触发重新下载避免串数据。命令详解通用用法actual command subcommand [options]所有命令都由 index.ts 中的register*Command函数注册到 commander 上。Accounts 账户管理# 列出所有账户默认排除已关闭账户 actual accounts list [--include-closed] # 创建账户 actual accounts create --name Checking [--offbudget] [--balance 50000] # 更新账户 actual accounts update id [--name New Name] [--offbudget true] # 关闭账户可指定余额转移到哪个账户/类别 actual accounts close id [--transfer-account id] [--transfer-category id] # 重新打开已关闭的账户 actual accounts reopen id # 删除账户 actual accounts delete id # 获取账户余额可按日期截断即截止日余额 actual accounts balance id [--cutoff 2026-01-31]Budgets 预算操作# 列出服务器上可用的预算 actual budgets list # 按 Sync ID 下载预算加密预算需传加密密码 actual budgets download syncId [--encryption-password pw] # 同步当前预算 actual budgets sync # 列出预算月份 actual budgets months # 查看指定月份 actual budgets month 2026-03 # 设置某类别某月预算金额单位为整数分 actual budgets set-amount --month 2026-03 --category id --amount 50000 # 设置结转carryover标志 actual budgets set-carryover --month 2026-03 --category id --flag true # 为下月预留资金 actual budgets hold-next-month --month 2026-03 --amount 10000 # 重置已预留的资金 actual budgets reset-hold --month 2026-03Categories 类别管理# 列出所有类别 actual categories list # 创建类别 actual categories create --name Groceries --group-id id [--is-income] # 更新类别 actual categories update id [--name Food] [--hidden true] # 删除类别可把交易转移到其他类别 actual categories delete id [--transfer-to id]Category Groups 类别组# 列出所有类别组 actual category-groups list # 创建类别组 actual category-groups create --name Essentials [--is-income] # 更新类别组 actual category-groups update id [--name New Name] [--hidden true] # 删除类别组可把其类别转移到其他组 actual category-groups delete id [--transfer-to id]Transactions 交易# 列出某账户在日期范围内的交易 actual transactions list --account id --start 2026-01-01 --end 2026-03-31 # 新增交易内联 JSONdata 是数组 actual transactions add --account id --data [{date:2026-03-13,amount:-5000,payee_name:Store}] # 从文件新增交易 actual transactions add --account id --file transactions.json # 带对账去重地导入交易--dry-run 可先预览 actual transactions import --account id --data [...] [--dry-run] # 更新某笔交易 actual transactions update id --data {notes:Updated note} # 删除某笔交易 actual transactions delete id从 transactions.ts 实现 可以看到几个值得留意的细节list的--account、--start、--end三个参数都是必填requiredOptionadd额外支持--learn-categories学习类别分配和--run-transfers处理转账两个开关默认关闭import调用的是api.importTransactions内部以defaultCleared: true导入视为已清算并具备基于imported_id的去重/对账能力--dry-run只预览不写入update和delete成功后返回{ success: true, id }方便脚本确认。Payees 收款方# 列出所有收款方 actual payees list # 列出常用收款方 actual payees common # 创建收款方 actual payees create --name Grocery Store # 更新收款方 actual payees update id --name New Name # 删除收款方 actual payees delete id # 合并多个收款方为一个目标 ID 逗号分隔的源 ID 列表 actual payees merge --target id --ids id1,id2,id3payees merge对整理重复商户名非常有用例如把 Starbucks、STARBUCKS #123 统一合并到主收款方。Tags 标签# 列出所有标签 actual tags list # 创建标签可带颜色和描述 actual tags create --tag vacation [--color #ff0000] [--description Vacation expenses] # 更新标签 actual tags update id [--tag trip] [--color #00ff00] # 删除标签 actual tags delete idRules 规则# 列出所有规则 actual rules list # 列出某个收款方适用的规则 actual rules payee-rules payeeId # 创建规则内联 JSONstage、conditionsOp、conditions、actions 等 actual rules create --data {stage:pre,conditionsOp:and,conditions:[...],actions:[...]} # 从文件创建规则 actual rules create --file rule.json # 更新规则需在 data 中携带规则 id actual rules update --data {id:...,stage:pre,...} # 删除规则 actual rules delete id规则与 Actual 界面中的规则一一对应stage表示执行阶段如preconditionsOp为条件组合方式and/orconditions与actions是结构与界面规则完全一致的 JSON 数组。用actual rules payee-rules payeeId可快速查看某个收款方会被哪些规则命中。Schedules 日程# 列出所有日程 actual schedules list # 创建日程date 支持 1st 这种自然语言日期表达 actual schedules create --data {name:Rent,date:1st,amount:-150000,amountOp:is,account:...,payee:...} # 更新日程--reset-next-date 可重置下次执行日期 actual schedules update id --data {name:Updated Rent} [--reset-next-date] # 删除日程 actual schedules delete id日程 JSON 中的amountOp指定金额匹配方式如isamount为整数分。Server 服务器辅助命令# 获取服务器版本 actual server version # 按名称反查实体 IDaccounts、categories 等类型 actual server get-id --type accounts --name Checking actual server get-id --type categories --name Groceries # 触发银行同步可指定账户 actual server bank-sync [--account id]get-id是脚本化流程中非常实用的命令先用名字查 ID再把 ID 传给其他命令。Sync 同步命令注册在命令树中的sync命令用于显式触发同步与budgets sync的功能一致适合在批量脚本前后调用。Query使用 ActualQL 查询数据query命令暴露了完整的 ActualQLActual Query Language能力底层调用api.aqlQuery()。ActualQL 的完整过滤/函数参考见 ActualQL 文档涵盖$transform、$month、$year及聚合函数等。子命令子命令说明query run执行一条 AQL 查询query tables列出可用表query fields table列出某表的字段与类型query run选项选项说明--table table要查询的表用actual query tables查看--select fields逗号分隔的待选字段--filter jsonJSON 格式过滤器如{amount:{$lt:0}}--where json--filter的别名不能同时使用--order-by fields字段及可选方向field1:desc,field2默认升序--limit n限制结果条数--offset n跳过前 N 条分页用--last n显示最近 N 笔交易快捷方式隐含--table transactions与--order-by date:desc--count只统计匹配行数--group-by fields逗号分隔的分组字段--file path从 JSON 文件读取完整查询对象-表示标准输入可查询的表与字段从 query.ts 的 TABLE_SCHEMA 可以看出当前支持 6 张表transactions、accounts、categories、payees、rules、schedules。transactions表包含id、account、date、amount、payee、category、notes、cleared、reconciled、is_parent、is_child、parent_id、sort_order等字段并支持通过点号访问关联实体字段如account.name、payee.name、category.name、category.group.name。--order-by的解析逻辑在 parseOrderBy以逗号分隔多个字段方向只能是asc或desc格式为field:desc不带冒号则为默认升序。示例# 显示最近 5 笔交易快捷方式 actual query run --last 5 # 用 --last 时覆盖默认列 actual query run --last 10 --select date,amount,notes # 按日期倒序查询交易并限制条数 actual query run --table transactions --select date,amount,payee.name --order-by date:desc --limit 10 # JSON 过滤——负金额即支出 actual query run --table transactions --filter {amount:{$lt:0}} --limit 5 # 使用 --where--filter 的别名对 SQL 用户更直观 actual query run --table transactions --where {payee.name:Grocery Store} --limit 5 # 统计全部交易数 actual query run --table transactions --count # 带过滤条件统计 actual query run --table transactions --filter {category.name:Groceries} --count # 按类别分组并聚合聚合表达式需通过 --file 提供 echo {table:transactions,groupBy:[category.name],select:[category.name,{amount:{$sum:$amount}}]} | actual query run --file - # 分页跳过前 20 条取接下来 10 条 actual query run --table transactions --order-by date:desc --limit 10 --offset 20 # 多字段排序 actual query run --table transactions --order-by date:desc,amount:asc --limit 10 # 从 JSON 文件运行查询 actual query run --file query.json # 从标准输入管道传入查询 echo {table:transactions,select:[date,amount],limit:5} | actual query run --file - # 列出可用表 actual query tables # 查看某表的字段 actual query fields transactions--last与--limit互斥源码会直接报错--count与--select互斥--filter与--where互斥这些冲突都会在 buildQueryFromFlags 中被显式校验。金额约定一律使用整数分所有金额在 CLI 中均以整数分表示CLI 值美元金额5000$50.00-12350-$123.50100$1.00例如要预算 $50就传5000。输出格式化差异table和csv输出会自动把分值转换为十进制如1665.00而非166500json输出则始终返回原始分值便于程序化处理。输出格式--format标志控制结果展示方式json默认——机器可读的 JSON 输出适合脚本处理。查询结果直接输出为记录数组bare array。table——人类可读的表格。金额字段自动格式化为十进制。csv——逗号分隔值便于导入电子表格。金额字段自动格式化为十进制。从 output.ts 的源码可以看到金额自动格式化的完整字段清单AMOUNT_FIELDSamount、balance、balance_available、balance_current、balance_limit、budgeted、spent、carryover。还有一个值得注意的安全细节CSV 输出内置了公式注入防护——当字符串值以、、-、、\t、\r开头时会加前缀防止被 Excel 等表格软件当作公式执行数字值如-25.00不会被引号包裹保证负金额仍是数值。使用--verbose可在 stderr 输出信息性消息便于调试和观察 CLI 正在做什么例如 Downloading budget ... for the first time...、Syncing budget ...。常见工作流查看本月预算actual budgets month 2026-03 --format table查询账户余额# 先按名称找到账户 ID actual server get-id --type accounts --name Checking # 再查余额 actual accounts balance id导出交易到 CSVactual transactions list --account id --start 2026-01-01 --end 2026-12-31 --format csv transactions.csv新增一笔交易actual transactions add --account id --data [{date:2026-03-14,amount:-2500,payee_name:Coffee Shop}]技巧与常见坑拆分交易Split transactions对交易做求和/计数时务必过滤is_parent: false以避免重复计算。拆分交易的父亲节点持有总额子节点持有各部分金额——两者都计入会把总额算两遍。避免快速连续请求每次 CLI 调用都会新建一个服务器连接。在紧凑循环里逐月查询如每月一次可能触发限流或认证失败。更优做法是用一个带日期范围过滤的查询一次性拉取全部数据然后在本地脚本中处理。未分类交易没有类别的交易其category.name为null按类别过滤或分组时要考虑这一点。AQL 不支持日期子字段date.month、date.year等不能作为查询字段使用。需要按月分组时用日期范围过滤拉取原始交易再在脚本中本地聚合。自签名 SSL 证书如果 Actual sync server 使用自签名 SSL 证书CLI 默认会拒绝连接。可以将你的 CA 证书加入系统信任证书库细节超出本文范围。另一种方式是通过环境变量允许连接到使用自签名证书的服务器NODE_TLS_REJECT_UNAUTHORIZED0 actual budgets list或为整个会话导出export NODE_TLS_REJECT_UNAUTHORIZED0 actual budgets list:::caution 安全警告 设置NODE_TLS_REJECT_UNAUTHORIZED0会禁用所有 TLS 证书校验使连接容易遭受中间人攻击。仅在可信网络环境、且你完全掌控服务器并了解风险时使用。 :::错误处理与脚本化约定非零退出码表示出错错误以纯文本写入 stderr如Error: message用--verbose可开启 stderr 上的信息性消息用于调试。从 index.ts 的错误处理 可以看到CLI 捕获所有异常后统一输出Error: ${message}到 stderr 并设置process.exitCode 1。这为脚本编写提供了稳定契约检查退出码判断成败解析 stdout 获取数据读取 stderr 定位错误。结合--format json与上述--last、--file -标准输入等特性你可以把 CLI 无缝嵌入 cron 任务、CI 流程或 shell/Python 脚本构建出完整的预算数据自动化体系。总结actual-app/cli把 Actual Budget 的全部核心数据操作能力开放到了终端从账户、预算、类别、交易、收款方、标签、规则、日程的增删改查到基于 ActualQL 的灵活查询再到 CSV 导出与脚本集成。理解它的配置优先级、缓存/锁机制、金额分值与输出格式约定就能安全高效地把它用于数据备份、对账、报表生成与自动化工作流。【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actual创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表