Oxidized 0.37.0 常用 CLI 命令详解

Oxidized 0.37.0 运维入口全解:oxidized 主命令 8 参数、oxidized-web REST API 全路由 curl 实测、rest_client/nagios 巡检脚本与 git 裸仓查历史。

OxidizedOxidized网络配置备份2026/10/22

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 APIHTTP 端点(默认 8888)节点查询、配置抓取、版本/差异、手动触发、巡检集成
官方辅助脚本源码 extra/ 目录程序化触发抓取(rest_client.rb)、Nagios 式巡检(nagios_check_failing_nodes.rb)、裸仓 git 查历史

说明:Oxidized 的主命令没有「子命令」设计(不像 systemctl 那样 verb 式),所有运行态操作都通过 REST API 完成——这是它与 RANCID 时代工具的显著差异。

三、前置条件

  1. 服务已按《Ubuntu 22.04 安装 Oxidized 指南》安装并 systemd 托管:
systemctl is-active oxidized

实测回显:

active
  1. 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}
  1. 版本/差异类端点(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/重定向到 /nodes302 ✓
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>&nbsp;
</div><div>&nbsp;
</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 到异地即完成备份系统的「备份」。

七、注意事项

  1. 配置变更不生效时先想重启:/reload 只重载节点清单;全局参数、输出、数据源改动都要 systemctl restart oxidized(实测见《Oxidized 0.37.0 配置参数详解》5.1)。
  2. /node/next 用 GET/PUT:POST 会得到 Sinatra 404 页(实测 5.4),写自动化脚本时别踩。
  3. /nodes/model/ 过滤用机型类名:LinuxGeneric 而非 linuxgeneric,否则静默返回空数组(实测 5.2)。
  4. 版本/差异端点依赖 git 输出:file 输出下 /node/version* 无数据;生产建议 git 输出。
  5. mtime 的语义:只在配置变化入库时更新,服务重启后、设备未变更时显示 unknown(实测 5.2),不是故障。
  6. 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 是为了可脚本化与可验证。

九、参考链接