Oxidized 0.37.0 常用 CLI 命令详解
Oxidized 0.37.0 运维入口全解:oxidized 主命令 8 参数、oxidized-web REST API 全路由 curl 实测、rest_client/nagios 巡检脚本与 git 裸仓查历史。
Oxidized 0.37.0 常用 CLI 命令详解
目标:汇总 Oxidized 0.37.0 日常运维的三类操作入口——
oxidized主命令、oxidized-web REST API(curl 实测)、官方辅助脚本,逐条给出真实命令与实测回显。全文在 Ubuntu 22.04.5 LTS 服务器实测通过(Oxidized 0.37.0 + oxidized-web 0.18.1,systemd 托管,配置目录 /etc/oxidized,备份对象 sw01)。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64,内核 6.8.0-138-generic)
- Oxidized 0.37.0(
oxidized --version实测输出0.37.0),oxidized-web 0.18.1,rugged 1.9.6 - 服务形态:systemd 单元
oxidized.service(Environment=OXIDIZED_HOME=/etc/oxidized,运行账号 oxidized) - 配置与产物目录:
/etc/oxidized/config(主配置)、/etc/oxidized/router.db(CSV 清单)、/etc/oxidized/configs/(file 输出)、/etc/oxidized/oxidized.git(git 输出,版本/差异 API 依赖) - 备份对象:Linux 设备 sw01(10.89.58.20,机型 linuxgeneric,账号 admin)
- 路由清单取证来源:oxidized-web 0.18.1 源码
lib/oxidized/web/webapp.rb(与 gem 安装目录内文件一致)
二、工具概览
Oxidized 0.37.0 的运维入口分三类:
| 入口 | 形态 | 用途 |
|---|---|---|
oxidized 主命令 | 单一可执行文件,8 个参数 | 启动守护进程、调试、诊断、穷举配置 |
| oxidized-web REST API | HTTP 端点(默认 8888) | 节点查询、配置抓取、版本/差异、手动触发、巡检集成 |
| 官方辅助脚本 | 源码 extra/ 目录 | 程序化触发抓取(rest_client.rb)、Nagios 式巡检(nagios_check_failing_nodes.rb)、裸仓 git 查历史 |
说明:Oxidized 的主命令没有「子命令」设计(不像 systemctl 那样 verb 式),所有运行态操作都通过 REST API 完成——这是它与 RANCID 时代工具的显著差异。
三、前置条件
- 服务已按《Ubuntu 22.04 安装 Oxidized 指南》安装并 systemd 托管:
systemctl is-active oxidized
实测回显:
active
- REST API 可达(oxidized-web 已按
extensions.oxidized-web: {load: true, listen: 0.0.0.0, port: 8888}启用):
curl -s http://127.0.0.1:8888/nodes.json | head -c 120
实测回显:
[{"name":"sw01","full_name":"sw01","ip":"10.89.58.20","group":"default","model":"LinuxGeneric","last":{"start":"2026-10-22 09:21:05 UTC","end":"2026-10-22 09:21:10 UTC","status":"success","time":5.325234613}
- 版本/差异类端点(5.9 节)依赖 git 输出,需已在
/etc/oxidized/config配置output.git并gem install rugged(配置方法见《Oxidized 0.37.0 配置参数详解》5.5 节)。
四、oxidized 主命令详解
4.1 --help 与 --version
oxidized --help
oxidized --version
实测回显(--help 全文):
usage: /usr/local/bin/oxidized [options]
-d, --debug turn on debugging
--daemonize Daemonize/fork the process
--support show support diagnostics and exit
--home-dir Oxidized home dir
--config-file Oxidized config file
-h, --help show usage
--show-exhaustive-config output entire configuration, including defaults
-v, --version show version
--version 实测回显:
0.37.0
4.2 前台启动(调试模式)
不跟参数直接运行即前台启动(生产由 systemd 托管,调试时手动前台跑最直观);-d/--debug 打开调试日志:
OXIDIZED_HOME=/etc/oxidized oxidized
实测回显(节选,Ctrl+C 停止):
2026-10-22 09:16:54.820375 I [6523:1400] Oxidized::CLI -- Oxidized starting, running as pid 6523
2026-10-22 09:16:54.820952 I [6523:1400] Oxidized::Nodes -- Loading nodes
2026-10-22 09:16:54.861523 I [6523:1400] Oxidized::Nodes -- Loaded 1 nodes
2026-10-22 09:16:54.983812 I [6523:2260] Oxidized::API::Web -- Oxidized-web server listening on 0.0.0.0:8888
2026-10-22 09:17:00.975862 I [6523:1400] Oxidized::Worker -- Configuration updated for /sw01
4.3 --daemonize
--daemonize 让进程 fork 到后台运行(不依赖 systemd 的场景),PID 写入 pid 配置项指定的文件。下面用「独立配置目录 + 独立端口 8899」做双实例实测(不影响正运行的主服务):
mkdir -p /opt/oxtest
sed -e 's|/etc/oxidized|/opt/oxtest|g' -e 's/port: 8888/port: 8899/' /etc/oxidized/config > /opt/oxtest/config
echo 'sw01:linuxgeneric' > /opt/oxtest/router.db
OXIDIZED_HOME=/opt/oxtest oxidized --daemonize
确认 PID 文件与新实例可用:
cat /opt/oxtest/pid
curl -s http://127.0.0.1:8899/nodes.json | head -c 120
实测回显:
17362
[{"name":"sw01","full_name":"sw01","ip":"10.89.58.20","group":"default","model":"LinuxGeneric","last":{"start":"2026-10-22 09:21:05 UTC","end":"2026-10-22 09:21:10 UTC","status":"success","time":5.325234613}
停止守护实例(按 PID 文件 kill),确认只剩 systemd 主实例:
kill $(cat /opt/oxtest/pid)
ps -ef | grep [o]xidized | grep -v grep | wc -l
实测回显:
1
⚠️ 注意:生产环境建议统一走 systemd 托管而非 --daemonize(systemd 提供开机自启与崩溃拉起);若 PID 文件指向的进程仍存活,重复启动会被拒绝并提示
A server is already running. Check <pid 文件路径>。
4.4 --support(诊断自检)
一键输出诊断信息,密码类敏感值自动脱敏(官方日志明确提示输出可能含敏感信息、分享前需检查):
OXIDIZED_HOME=/etc/oxidized oxidized --support
实测回显(节选):
> :warning:
> The --support option is intended for diagnostic purposes and may include sensitive information.
> Remove any sensitive data before sharing this output.
## Oxidized Support Data
- Timestamp: 2026-10-22T09:26:38Z
- Oxidized version: 0.37.0
- OS release: Ubuntu 22.04.5 LTS
- Container hint (/etc/service/oxidized/run exists): false
- Ruby engine: ruby
- Ruby version: 3.0.2p107 (x86_64-linux-gnu)
- Working directory: /
- Gem paths: /root/.local/share/gem/ruby/3.0.0, /var/lib/gems/3.0.0, ...
### Environment Variables
OXIDIZED_HOME=/etc/oxidized
### Configuration Files
- /etc/oxidized/config exists: yes
```yaml
---
username: admin
password: [REDACTED]
model: linuxgeneric
resolve_dns: true
```
4.5 --show-exhaustive-config
输出含全部默认值的穷举配置(比配置文件多出未显式写的键),改参数前「查默认值」最快路径:
OXIDIZED_HOME=/etc/oxidized oxidized --show-exhaustive-config
实测回显(节选,首 42 行):
---
username: admin
password: q1w2e3r4
model: linuxgeneric
resolve_dns: true
interval: 3600
debug: false
run_once: false
threads: 30
use_max_threads: false
timeout: 20
timelimit: 300
retries: 3
prompt: !ruby/regexp /^([\w.@-]+[#>]\s?)$/
next_adds_job: false
vars: {}
groups: {}
group_map: {}
models: {}
pid: "/etc/oxidized/pid"
extensions:
oxidized-web:
load: true
listen: 0.0.0.0
port: 8888
crash:
directory: "/etc/oxidized/crashes"
hostnames: false
stats:
history_size: 10
input:
default: ssh, telnet
debug: false
ssh:
secure: false
ftp:
passive: true
utf8_encoded: true
output:
default: file
git:
user: Oxidized
4.6 --home-dir 与 --config-file
两个参数改「配置从哪读」:--home-dir 等价于环境变量 OXIDIZED_HOME(默认 ~/.config/oxidized),--config-file 改配置文件名(默认 config)。多实例隔离时用:
oxidized --home-dir /etc/oxidized --config-file config
实测说明:与 OXIDIZED_HOME=/etc/oxidized oxidized 效果一致(本文统一用环境变量方式,systemd 单元里写 Environment= 即可)。
五、oxidized-web REST API 详解(curl 实测)
5.1 端点总表
oxidized-web 0.18.1 全部路由(源码 webapp.rb 取证,标注实测结果):
| 方法 | 端点 | 用途 | 实测 |
|---|---|---|---|
| GET | / | 重定向到 /nodes | 302 ✓ |
| GET | /nodes[.json] | 节点列表 | ✓ |
| GET | /nodes/model/<Model>[.json] | 按机型过滤 | ✓ |
| GET | /nodes/group/<Group>[.json] | 按分组过滤 | ✓ |
| POST | /nodes/conf_search[.json] | 配置全文检索 | ✓ |
| GET | /nodes/stats[.json] | 每节点抓取统计 | ✓ |
| GET | /reload[.json] | 重载节点清单 | ✓ |
| GET | /node/fetch/:node[.json] | 取当前配置 | ✓ |
| GET/PUT | /node/next/:node | 立即抓取(插队) | ✓(POST 返回 404) |
| GET | /node/show/:node[.json] | 单节点详情 | ✓ |
| GET | /node/version[.json]?node_full= | 版本列表(需 git 输出) | ✓ |
| GET | /node/version/view[.json] | 查看某版本全文(需 git 输出) | ✓ |
| GET/POST | /node/version/diffs | 两版本差异(需 git 输出) | ✓ |
5.2 节点列表与过滤
curl -s http://127.0.0.1:8888/nodes.json
实测回显:
[{"name":"sw01","full_name":"sw01","ip":"10.89.58.20","group":"default","model":"LinuxGeneric","last":{"start":"2026-10-22 09:21:05 UTC","end":"2026-10-22 09:21:10 UTC","status":"success","time":5.325234613},"vars":{},"mtime":"2026-10-22 09:21:11 UTC","status":"success","time":"2026-10-22 09:21:10 UTC"}]
字段解读:status 是最近一轮抓取结果(success/no_connection/never),last.time 为耗时(秒),mtime 为最近一次「配置变化入库」时间(从未变过或服务重启后未再变更时显示 unknown——Oxidized 只在配置变化时更新 mtime)。按机型过滤(注意要写机型类名):
curl -s http://127.0.0.1:8888/nodes/model/LinuxGeneric.json | head -c 200
实测回显:
[{"name":"sw01","full_name":"sw01","ip":"10.89.58.20","group":"default","model":"LinuxGeneric","last":{"start":"2026-10-22 09:21:05 UTC","end":"2026-10-22 09:21:10 UTC","status":"success","time":5.325234613},"vars":{},"mtime":"2026-10-22 09:21:11 UTC","status":"success","time":"2026-10-22 09:21:10 UTC"}]
⚠️ 实测:用小写
linuxgeneric过滤返回[]——/nodes/model/匹配的是节点对象里的机型类名(LinuxGeneric),与配置里的蛇形小写不同。按分组过滤同理:curl -s http://127.0.0.1:8888/nodes/group/default.json(实测回显同上结构,group 为 default)。
5.3 配置抓取与全文检索
取某台设备当前配置:
curl -s http://127.0.0.1:8888/node/fetch/sw01 | head -12
实测回显:
###### THE HOSTNAME ######
sw01
###### THE HOSTS ######
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00:: ip6-localnet
ff00:: ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.89.58.20 sw01
按正则检索所有设备配置内容(工单排查「哪台设备配了这个 ACL/VLAN」时高频使用):
curl -s -X POST -d "search_in_conf_textbox=THE HOSTNAME" http://127.0.0.1:8888/nodes/conf_search.json
实测回显:
[{"node":"sw01","full_name":"sw01"}]
5.4 立即抓取 /node/next(实测 POST 404)
把指定设备插队立即抓取,只支持 GET/PUT,不支持 POST(实测 POST 直接撞上 Sinatra 404 页):
curl -s -X POST http://127.0.0.1:8888/node/next/sw01 | head -8
实测回显(404 页节选):
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body { text-align:center;font-family:helvetica,arial;font-size:22px;
color:#888;margin:20px}
#c {margin:0 auto;width:500px;text-align:left}
</style>
</head>
<body>
<h2>Sinatra doesn’t know this ditty.</h2>
正确姿势(GET):
curl -s http://127.0.0.1:8888/node/next/sw01
实测回显:空响应体(HTTP 303 语义),服务日志随即出现入队与抓取动作:
2026-10-22 09:22:15.519852 I [8751:puma srv tp 001] Oxidized::Nodes -- Add node sw01 to running jobs
2026-10-22 09:22:22.275355 I [8751:1380] Oxidized::Worker -- Configuration updated for /sw01
验证要点:日志出现 Add node <name> to running jobs 即触发成功。
5.5 统计与清单重载
curl -s http://127.0.0.1:8888/nodes/stats.json
curl -s http://127.0.0.1:8888/reload.json
实测回显:
{"sw01":"#<Oxidized::Node::Stats:0x000056c091d01670>"}
["reloaded list of nodes"]
说明:/nodes/stats.json 在 0.18.1 里对单节点返回的是 Stats 对象的 Ruby inspect 字符串(非结构化 JSON),可作为「节点是否有统计记录」的存在性判断用;/reload 让进程重读清单文件(新增/删除设备后无需重启进程,但配置参数改动仍需重启,见《Oxidized 0.37.0 配置参数详解》第三章)。
5.6 单节点详情
curl -s http://127.0.0.1:8888/node/show/sw01.json
实测回显(git 输出启用时):
{"name":"sw01","full_name":"sw01","ip":"10.89.58.20","group":null,"model":"LinuxGeneric","last":{"start":"2026-10-22 09:58:17 UTC","end":"2026-10-22 09:58:22 UTC","status":"success","time":5.327179032},"vars":{},"mtime":"unknown"}
5.7 版本列表与版本全文(需 git 输出)
版本列表(node_full 传「分组/节点名」或纯节点名):
curl -s 'http://127.0.0.1:8888/node/version.json?node_full=sw01'
实测回显(节选,两个历史版本):
[{"date":"2026-10-22 09:36:50 +0000","time":"2026-10-22 09:36:50 +0000","oid":"f91b00781b144d9af5f8dba9bcbe8e5ce0bbf085","author":{"name":"Oxidized","email":"oxidized@example.com","time":"2026-10-22 09:36:50 +0000"},"message":"update /sw01"},{"date":"2026-10-22 09:23:43 +0000",...,"oid":"d247c3fb29be82a131c2d68e91795e517a71d72e",...}]
取某版本全文(num 从最新版递减编号,epoch 为该版本时间戳):
curl -s "http://127.0.0.1:8888/node/version/view.json?node=sw01&oid=d247c3fb29be82a131c2d68e91795e517a71d72e&num=2&epoch=1792661023" | head -8
实测回显(JSON 数组,每元素一行配置):
["\n","###### THE HOSTNAME ######\n","sw01\n","\n","###### THE HOSTS ######\n","127.0.0.1\tlocalhost\n","::1\tlocalhost ip6-localhost ip6-loopback\n","fe00::\tip6-localnet\n","ff00::\tip6-mcastprefix\n","ff02::1 ip6-allnodes\n","ff02::2 ip6-allrouters\n","10.89.58.20\tsw01\n","\n","###### THE INTERFACES ######\n",...]
5.8 版本差异(diff)
对比最新版与上一版(同上参数,端点换 /node/version/diffs):
curl -s "http://127.0.0.1:8888/node/version/diffs?node=sw01&oid=d247c3fb29be82a131c2d68e91795e517a71d72e&num=2&epoch=1792661023" | grep -A8 'MOTD' | head -14
实测回显(节选,新增行带 + 且有 added 样式类):
</div><div> ###### MOTD ######
</div><div> sw01 access switch, firmware 15.2(4)E1, location IDC-A1
</div><div>
</div><div>
</div><div>
</div><div> ###### PASSWD ######
</div><div> root:x:0:0:root:/root:/bin/bash
</div></div>
<div class='diffs_new'><div>diff --git a/sw01 b/sw01
--
</div><div> ###### MOTD ######
</div><div> sw01 access switch, firmware 15.2(4)E1, location IDC-A1
</div><div class='added'>+sw01 access switch, firmware 15.2(4)E1, location IDC-A1
</div><div class='added'>+vlan 10 name OFFICE
解读:本次差异正是设备侧 /etc/motd 追加的 vlan 10 name OFFICE 行——审计「两次备份之间设备改了什么」即此能力。Web UI 上同一数据在 http://<host>:8888/nodes 页面点设备名即可视化查看。
六、官方辅助工具详解
6.1 rest_client.rb(程序化触发抓取)
源码 extra/rest_client.rb 是官方给出的 Ruby 客户端封装:读自身配置的 rest 键(默认 127.0.0.1:8888),提供 Oxidized::RestClient.next(name: <节点>) 触发 PUT /node/next/<name>。适合从工单系统/自动化脚本里触发单台设备立即备份:
ruby -e "require '/opt/rest_client.rb'; r = Oxidized::RestClient.next(name: :sw01); puts 'HTTP ' + r.code.to_s"
实测回显:
HTTP 303
随即服务日志确认入队:
2026-10-22 09:59:04.515685 I [17290:puma srv tp 001] Oxidized::Nodes -- Add node sw01 to running jobs
6.2 nagios_check_failing_nodes.rb(巡检脚本)
源码 extra/nagios_check_failing_nodes.rb 是 Nagios 风格巡检插件:读 /nodes.json,有失败节点输出 [CRIT] 并 exit 2,有从未备份节点输出 [WARN] 并 exit 1,全部成功输出 [OK] 并 exit 0(源码逻辑),可直接挂进 Zabbix/Nagios/CI 做每日备份巡检:
ruby /opt/nagios_check_failing_nodes.rb
实测回显(当前所有节点备份正常):
[OK] Backup of all nodes completed successfully.
echo $?
实测回显:
0
6.3 git 裸仓查历史(配合 git 命令)
启用 git 输出后,备份历史就是一个标准裸仓库,git 命令直接可查(5.7/5.8 的 API 即封装它):
git --git-dir=/etc/oxidized/oxidized.git log --format='%h %an %ad %s' --date=iso | head -3
实测回显:
d247c3f Oxidized 2026-10-22 09:23:43 +0000 update /sw01
c3107e4 Oxidized 2026-10-22 09:23:09 +0000 update /sw01
查看任意一版完整配置(对应 API 的 version/view):
git --git-dir=/etc/oxidized/oxidized.git show d247c3f:sw01 | head -6
实测回显(节选):
###### THE HOSTNAME ######
sw01
###### THE HOSTS ######
127.0.0.1 localhost
💡 说明:
git --git-dir=<裸仓> show <短哈希>:<设备名>即可离线翻任意历史版本,无需起服务;把裸仓整目录 rsync 到异地即完成备份系统的「备份」。
七、注意事项
- 配置变更不生效时先想重启:
/reload只重载节点清单;全局参数、输出、数据源改动都要systemctl restart oxidized(实测见《Oxidized 0.37.0 配置参数详解》5.1)。 /node/next用 GET/PUT:POST 会得到 Sinatra 404 页(实测 5.4),写自动化脚本时别踩。/nodes/model/过滤用机型类名:LinuxGeneric而非linuxgeneric,否则静默返回空数组(实测 5.2)。- 版本/差异端点依赖 git 输出:file 输出下
/node/version*无数据;生产建议 git 输出。 - mtime 的语义:只在配置变化入库时更新,服务重启后、设备未变更时显示
unknown(实测 5.2),不是故障。 - API 无内置认证:oxidized-web 本身没有登录/Token 机制,
listen: 0.0.0.0时务必用防火墙/反代限制来源,或仅监听 127.0.0.1 由前端代理鉴权。
八、常见问题(FAQ)
Q1:oxidized --version 之外想看支持的机型有哪些?
官方清单在源码 docs/Supported-OS-Types.md(0.37.0 含 205 条机型条目);也可看本机已装模型目录:ls /var/lib/gems/3.0.0/gems/oxidized-0.37.0/lib/oxidized/model/*.rb | wc -l(实测 198 个模型文件)。
Q2:curl 返回空但服务在跑?
先确认 oxidized-web 已启用且监听地址包含你访问的地址(listen: 127.0.0.1 时远程访问必空),再 journalctl -u oxidized | grep listening 看实际监听。
Q3:--support 会泄露密码吗?
不会原样输出——凭据自动脱敏为 [REDACTED](实测 4.4),但仍建议按官方提示检查后再外发。
Q4:巡检脚本对「从未备份过」的节点报什么?
exit 1 + [WARN] Pending backup: <节点名>(源码分支逻辑);只有抓取失败才 [CRIT] + exit 2。
Q5:能否不用 curl 而用 Web 页面完成同样操作?
可以:http://<host>:8888/nodes 页面即节点列表,含状态、版本历史与 diff 入口;本篇用 curl 是为了可脚本化与可验证。
九、参考链接
- oxidized-web 路由源码:https://github.com/ytti/oxidized-web/blob/main/lib/oxidized/web/webapp.rb (0.18.1)
- 官方 REST API 说明:https://github.com/ytti/oxidized/blob/main/docs/Ruby-API.md 与 README「RESTful API」节(0.37.0 源码内含)
- 辅助脚本目录:https://github.com/ytti/oxidized/tree/main/extra (rest_client.rb / nagios_check_failing_nodes.rb)
- 本专栏相关篇目:《Oxidized 0.37.0 介绍与选型指南》(https://www.quzuo.net/document/nzEHSUbDqEuW )、《Ubuntu 22.04 安装 Oxidized 指南》(https://www.quzuo.net/document/NcutoU8bDsiu )、《Oxidized 0.37.0 配置参数详解》(https://www.quzuo.net/document/YK5CjYK3QIHk )