Nullboard Agent 1.1.0 常用 CLI 命令与工具详解

nbagent 1.1.0 命令行全解:启动参数组合、token 管理、systemd 巡检、备份协议四接口 curl 直调与备份数据巡检恢复,全部命令实测。

Nullboard看板自托管2026/10/24

Nullboard Agent 1.1.0 常用 CLI 命令与工具详解

目标:把 Nullboard 备份 Agent 相关的命令行操作一次讲全——nbagent 1.1.0 的启动参数与运行方式、token 管理、备份协议四大接口的 curl 直调、备份数据的巡检与恢复命令。全部命令与回显在 Ubuntu 22.04 + nbagent 1.1.0(Python 3.10.12)环境实测通过。

一、环境信息

项目取值
操作系统Ubuntu 22.04(Python 3.10.12)
nbagent1.1.0(PyPI 安装,/usr/local/bin/nbagent)
Agent 数据目录/var/lib/nbagent/(systemd 托管实例)
Agent 监听0.0.0.0:10001
systemd 单元nbagent.service(部署见《Ubuntu 22.04 安装 Nullboard 2023.11.05 指南》第七章)
Access Token(本机实测值)46f95cf448a24a96b1f4c7c7ed5eb369(部署时随机生成,读者以自己环境为准)

工具口径说明:Nullboard 前端本体是单 HTML 文件应用,无命令行;官方备份 Agent(apankrat/nullboard-agent,Windows 托盘程序)是图形程序也无 CLI。Linux 服务器上的 CLI 入口就是 nbagent(备份协议与官方 Windows 版完全一致),本文所有 CLI 内容以 nbagent 1.1.0 为准;此外备份协议本身是纯 HTTP,curl 即第二工具(第五章)。

二、工具概览

Nullboard 日常运维涉及四类命令工具,各司其职:

工具形态用途
nbagentCLI 程序启动备份服务、管理 token、指定监听与数据目录
systemctl / journalctlsystemd 工具生产托管、启停、日志与状态巡检
curlHTTP 客户端直调备份协议四接口(checkStatus/saveConfig/saveBoard/nukeBoard),排障与自动化
find / du / cat / wcshell 工具备份目录巡检、体积统计、rev 文件查看与恢复

如何选:日常状态确认用 systemctl 一条命令;配对失败排障用 curl 探测协议层;数据恢复与审计走文件层命令。四层由浅入深,覆盖从「服务活着吗」到「这条备份能不能救回来」的全部问题。

三、前置条件

  • nbagent 已安装并可执行(安装步骤见安装指南 7.1 节):
which nbagent && pip3 show nbagent | head -3

实测回显:

/usr/local/bin/nbagent
Name: nbagent
Version: 1.1.0
Summary: A Nullboard backup agent for Unix systems
  • 知道当前 Access Token(curl 直调必带):
python3 -c "import json;print(json.load(open('/var/lib/nbagent/app-config.json'))['auth'])"

实测回显:

46f95cf448a24a96b1f4c7c7ed5eb369
  • 服务器本机 curl 验证时若配置了 http_proxy 环境变量,一律加 --noproxy "*",否则本机请求会被代理拦截(实测该环境返回 502,详见第八章 Q3)。

四、nbagent 命令详解

4.1 帮助与版本查看

--help 输出全部参数与默认值:

nbagent --help

实测回显(逐行照抄):

Usage: nbagent [OPTIONS]

  A Nullboard backup agent

Options:
  --addr TEXT            Bind to address  [default: 0.0.0.0]
  --port INTEGER         Use custom port  [default: 10001]
  --data TEXT            Directory for data  [default:
                         /root/.local/share/nbagent]
  --reset-token          Generate a new random auth token
  --override-token TEXT  Use a custom auth token
  --help                 Show this message and exit.

版本号不在 --help 里(nbagent 无 --version 参数),查版本用 pip:

pip3 show nbagent | grep -E '^(Name|Version|Location)'

实测回显:

Name: nbagent
Version: 1.1.0
Location: /usr/local/lib/python3.10/dist-packages

说明:Location 即源码所在,其下 nbagent/main.py(254 行)是全部实现,排障时可直接阅读。

4.2 启动方式与参数组合

nbagent 的典型启动形态共四种,按场景选用:

① 默认启动(试运行):全部默认值,前台运行,Ctrl+C 停止:

nbagent

实测回显(节选,token 为随机值):

 * [i] Using data directory /root/.local/share/nbagent
 * [i] Config saved to /root/.local/share/nbagent/app-config.json
 * [!] Nullboard token: 23d650c082c2433192b8d817dbf55b06
 * [i] Server listening 0.0.0.0:10001...
 * Serving Flask app 'nbagent.main'
 * Debug mode: off

② 指定目录与监听(服务器正式口径,端口取 19996 以避开 systemd 实例占用的 10001 做演示):

nbagent --addr 127.0.0.1 --port 19996 --data /var/lib/nbagent

实测回显(前台运行,6 行全量):

 * [i] Using data directory /var/lib/nbagent
 * [i] Config loaded from /var/lib/nbagent/app-config.json
 * [!] Nullboard token: 46f95cf448a24a96b1f4c7c7ed5eb369
 * [i] Server listening 127.0.0.1:19996...
 * Serving Flask app 'nbagent.main'
 * Debug mode: off

说明:数据目录已初始化过时日志从 Config saved to 变为 Config loaded from(读已有配置而非新建)——这是判断「目录是否首次初始化」的便捷信号;[!] Nullboard token 行读取的是该目录 app-config.json 里的既有凭据,同一目录反复启动 token 不变。

③ 固定 token 启动(自动化部署):

nbagent --override-token 9f2c7b1e5a8d4f30aa11bb22cc33dd44 --data /tmp/nbtest --port 19999

实测回显(启动段):

 * [i] Using data directory /tmp/nbtest
 * [i] Config saved to /tmp/nbtest/app-config.json
 * [!] Nullboard token: 9f2c7b1e5a8d4f30aa11bb22cc33dd44
 * [i] Server listening 0.0.0.0:19999...

④ 重置 token(凭据轮换):

nbagent --reset-token --data /tmp/nbrt --port 19998

实测回显(启动段,token 为新生成随机值):

 * [i] Using data directory /tmp/nbrt
 * [i] Config saved to /tmp/nbrt/app-config.json
 * [!] Nullboard token: b7901a7540ac4c8e948c10be64e775ae
 * [i] Server listening 0.0.0.0:19998...

参数组合速查:

命令效果适用
nbagent默认监听 0.0.0.0:10001,数据在 ~/.local/share/nbagent本机试运行
nbagent --addr 127.0.0.1 --port 10001 --data /var/lib/nbagent只监听本机回环Agent 与浏览器同机、收紧暴露面
nbagent --port 10002 --data /var/lib/nbagent2第二实例多套独立备份(各自 token/目录)
nbagent --override-token <值> --data <目录>固定凭据启动脚本化部署、灾备演练
nbagent --reset-token --data <目录>重新生成随机凭据token 疑似泄漏轮换

4.3 systemd 托管与状态巡检

生产环境不手工前台跑 nbagent,用 systemd 单元托管(单元文件全文见安装指南 7.3 节)。日常巡检命令组:

systemctl is-active nbagent
systemctl is-enabled nbagent
systemctl status nbagent --no-pager -n 0

实测回显:

active
enabled
● nbagent.service - Nullboard Backup Agent (nbagent)
     Loaded: loaded (/etc/systemd/system/nbagent.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2026-10-24 01:26:23 UTC; 6min ago
   Main PID: 4499 (nbagent)
      Tasks: 1 (limit: 629145)
     Memory: 17.8M
        CPU: 128ms
     CGroup: /system.slice/nbagent.service
             └─4499 /usr/bin/python3 /usr/local/bin/nbagent --addr 0.0.0.0 --port 10001 --data /var/lib/nbagent

说明:Memory: 17.8M 是本实测环境的常驻内存量级,资源占用极小;Main PID 对应的命令行即当前生效的启动参数,改 unit 后可用它核对。

启停与改配:

systemctl restart nbagent
systemctl stop nbagent
systemctl daemon-reload

服务启停日志查看:

journalctl -u nbagent --no-pager -n 5

实测回显:

Oct 24 01:13:51 nullboard-server systemd[1]: Started Nullboard Backup Agent (nbagent).
Oct 24 01:26:23 nullboard-server systemd[1]: Stopping Nullboard Backup Agent (nbagent)...
Oct 24 01:26:23 nullboard-server systemd[1]: nbagent.service: Deactivated successfully.
Oct 24 01:26:23 nullboard-server systemd[1]: Stopped Nullboard Backup Agent (nbagent).
Oct 24 01:26:23 nullboard-server systemd[1]: Started Nullboard Backup Agent (nbagent).

业务日志观测:nbagent 的业务日志(保存成功、鉴权拒绝、落盘错误)写向进程 stdout/stderr,分三个级别——[i] 信息、[!] 需注意、[e] 错误。前台运行时逐条即时可见,实测一组典型输出(saveBoard 一次、错误 token 一次、DELETE 不存在看板一次):

 * [i] Saved board 'Journal Probe' (8888888888888), rev 1...
 * [!] Unauthorized request from 127.0.0.1 rejected
 * [e] Error renaming /tmp/nbfg/boards/7777777777777 to /tmp/nbfg/deleted/7777777777777: [Errno 2] No such file or directory: '/tmp/nbfg/boards/7777777777777' -> '/tmp/nbfg/deleted/7777777777777'

要点:[i] Saved board '<标题>' (<看板ID>), rev <N>... 即每次成功备份;[!] Unauthorized request from <IP> rejected 是 401 鉴权失败的留痕;[e] Error renaming ... 对应 DELETE 不存在看板。⚠️ 部分精简系统环境的 journald 不转发服务进程 stdout,此时 journal 里只有上述启停元日志、看不到业务行——排障时改用前台运行观察,或直接用第五章 curl 探测确认业务状态。

4.4 备份协议四接口 curl 直调

Nullboard 备份协议在源码 SimpleBackup 类中定义(nullboard.html L2469-L2550),共四个操作,全部以 X-Access-Token 头鉴权。用 curl 可脱离浏览器直接操作,是排障与自动化的利器。以下每条均为主环境实测。

① checkStatus——探测 Agent 存活(浏览器「Check the setup」按钮即此请求):

TOKEN=$(python3 -c "import json;print(json.load(open('/var/lib/nbagent/app-config.json'))['auth'])")
curl -s --noproxy "*" -w "\nHTTP %{http_code}\n" -X PUT http://127.0.0.1:10001/config \
     -H "X-Access-Token: $TOKEN" \
     -d "self=http://192.168.31.10/nullboard.html"

实测回显:

true
HTTP 200

说明:PUT /config 不带 conf 字段时即是 checkStatus(nbagent 对两种请求同一路由,self 表单字段记录发起方页面地址,仅作存档不参与逻辑)。

② saveBoard——写入一次看板备份:

curl -s --noproxy "*" -w "\nHTTP %{http_code}\n" -X PUT http://127.0.0.1:10001/board/1618401166671 \
     -H "X-Access-Token: $TOKEN" \
     -d "self=http://192.168.31.10/nullboard.html" \
     --data-urlencode 'data={"revision":7,"title":"Ops Board","lists":[]}' \
     --data-urlencode 'meta={"current":{"revision":7},"undo":[]}'

实测回显:

true
HTTP 200

验证落盘(rev 号取自 data 内的 revision 字段):

ls /var/lib/nbagent/boards/1618401166671/ && cat /var/lib/nbagent/boards/1618401166671/rev-00000007.json

实测回显:

meta.json
rev-00000000.json
rev-00000003.json
rev-00000005.json
rev-00000007.json
{
  "revision": 7,
  "title": "Ops Board",
  "lists": []
}

③ saveConfig——写入前端配置快照:

curl -s --noproxy "*" -w "\nHTTP %{http_code}\n" -X PUT http://127.0.0.1:10001/config \
     -H "X-Access-Token: $TOKEN" \
     -d "self=http://192.168.31.10/nullboard.html" \
     --data-urlencode 'conf={"maxUndo":50,"theme":"dark","fontSize":14}'

实测回显:

true
HTTP 200

④ nukeBoard——删除看板备份(Nullboard 里删除看板时浏览器自动发起):

curl -s --noproxy "*" -w "\nHTTP %{http_code}\n" -X DELETE http://127.0.0.1:10001/board/1618401166671 \
     -H "X-Access-Token: $TOKEN"
ls -d /var/lib/nbagent/boards/1618401166671 /var/lib/nbagent/deleted/1618401166671 2>&1

实测回显:

true
HTTP 200
ls: cannot access '/var/lib/nbagent/boards/1618401166671': No such file or directory
/var/lib/nbagent/deleted/1618401166671

说明:nuke 是 boards/<id>/ 整目录 rename 到 deleted/<id>/,数据并未删除;对不存在的看板 ID 重复 DELETE 时 HTTP 仍 200 但响应体为 false(实测值),且 journalctl 出现 Error renaming ...。

⑤ 鉴权失败路径(排障对照用):

curl -s --noproxy "*" -w "\nHTTP %{http_code}\n" -X PUT http://127.0.0.1:10001/config \
     -H "X-Access-Token: wrong-token" -d "self=x"

实测回显:

<!doctype html>
<html lang=en>
<title>401 Unauthorized</title>
<h1>Unauthorized</h1>
<p>The server could not verify that you are authorized to access the URL requested. You either supplied the wrong credentials (e.g. a bad password), or your browser doesn&#39;t understand how to supply the credentials required.</p>
HTTP 401

五、数据巡检与恢复命令

备份的价值在能恢复。围绕 /var/lib/nbagent 的巡检与恢复命令组如下(均已实测)。

清单巡检——确认哪些看板有备份、各有哪些修订:

find /var/lib/nbagent -type f | sort

实测回显:

/var/lib/nbagent/app-config.json
/var/lib/nbagent/boards/1618401166671/meta.json
/var/lib/nbagent/boards/1618401166671/rev-00000000.json
/var/lib/nbagent/boards/1618401166671/rev-00000003.json
/var/lib/nbagent/boards/1618401166671/rev-00000005.json
/var/lib/nbagent/deleted/1618401166671/meta.json
/var/lib/nbagent/deleted/1618401166671/rev-00000000.json

体积巡检——评估磁盘占用:

du -sh /var/lib/nbagent
du -ah /var/lib/nbagent | sort -k2 | head -12

实测回显:

48K     /var/lib/nbagent
48K     /var/lib/nbagent
4.0K    /var/lib/nbagent/app-config.json
24K     /var/lib/nbagent/boards
20K     /var/lib/nbagent/boards/1618401166671
4.0K    /var/lib/nbagent/boards/1618401166671/meta.json
4.0K    /var/lib/nbagent/boards/1618401166671/rev-00000000.json
4.0K    /var/lib/nbagent/boards/1618401166671/rev-00000003.json
4.0K    /var/lib/nbagent/boards/1618401166671/rev-00000005.json
16K     /var/lib/nbagent/deleted
12K     /var/lib/nbagent/deleted/1618401166671
4.0K    /var/lib/nbagent/deleted/1618401166671/meta.json
4.0K    /var/lib/nbagent/deleted/1618401166671/rev-00000000.json

看板内容查看——rev 文件是可读 JSON:

wc -c /var/lib/nbagent/boards/1618401166671/rev-00000005.json
cat /var/lib/nbagent/boards/1618401166671/rev-00000005.json

实测回显:

58 /var/lib/nbagent/boards/1618401166671/rev-00000005.json
{
  "revision": 5,
  "title": "Ops Board",
  "lists": []
}

恢复看板——rev 文件与 Nullboard「Export board」产物同为 .nbx 格式(官方备份文档明示 ".nbx files are the same as those created by the Export board function and they can be imported the same way",来源 nullboard.io/backups,查询日期 2026-10-24)。恢复路径二选一:

  • 把目标 rev 文件拷到本地,在 Nullboard 看板菜单用 Import board 选择该文件导入;
  • 浏览器端配置了同一 Agent 时,Auto-backups 对话框重新保存即可触发看板重备份恢复。

六、注意事项

  • curl 直调必带 --noproxy "*"(环境有 http_proxy 时):本机实测中缺它一律 502,读者排障时先排除代理干扰;
  • self 表单字段不可省:nbagent 的 save_board 逻辑读取表单字段但不校验 self;浏览器实际请求总带 self,手工模拟保持一致可减少变量;
  • data/meta 是 URL 表单字段不是 JSON body:要用 --data-urlencode 传 JSON 字符串,直接 -d 传含 &/空格的 JSON 会截断表单;
  • rev 号以 data 内 revision 为准:meta 里的 revision 不参与文件命名(源码 data.get("revision", "0"));
  • override 与 reset token 都会立即写回 app-config.json:在 systemd 托管实例的数据目录上执行会直接换掉生产凭据,浏览器端需重新配对——演练请用独立 --data 目录;
  • deleted/ 只增不减:清理策略需自行定时处理(如保留 30 天以上再删)。

七、常见问题

Q1:nbagent: command not found? pip 脚本目录不在 PATH。pip3 show nbagent 确认已装后 find / -name nbagent -type f 2>/dev/null 定位实际路径(root 常见为 /usr/local/bin/nbagent),或改用 venv 安装后以绝对路径启动。

Q2:日志里一直刷 Unauthorized request ... rejected? 有客户端在用过期/错误 token 持续请求。多见于换 token(--reset-token / --override-token)后浏览器未重新配对,或旧的自动化脚本还在跑。定位来源:业务日志行自带来源 IP([!] Unauthorized request from <IP> rejected),前台运行直接观察;journald 环境用 journalctl -u nbagent --no-pager | grep Unauthorized,若 journal 无业务行(见 4.3 节说明)则改前台观察或从防火墙/访问日志定位,逐条修正对应客户端。

Q3:本机 curl 全部 502? 环境变量 http_proxy/https_proxy 把 127.0.0.1 请求也发给了代理。加 --noproxy "*"(或 export no_proxy=127.0.0.1,localhost)后复测。本环境实测对照:不带该参数 502,带后协议接口全部正常。

Q4:saveBoard 返回 false 但 HTTP 200? nbagent 内部异常时返回体是 false(路由 try/except 兜底,源码 main.py L104-L122)。常见原因是 data/meta 不是合法 JSON(表单被截断)。修正传参方式(--data-urlencode)后重试,并以 journalctl 的 Error saving board 行定位细节。

Q5:想每天定时全量备份到另一块盘? nbagent 的 rev 文件即完整快照,直接用 cron/rsync 同步目录即可,例如把 /var/lib/nbagent 每日同步到 /backup/nbagent(rsync 增量、保留目录结构)。无需调任何 API;若要跨机走协议,用 curl 循环各看板调 saveBoard 亦可,但文件层同步更简单可靠。

八、参考链接