ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

用Codex写Linux巡检脚本:AI生成,人控执行的安全实践

2026/9/8 13:56:45 拓冰建站 浏览量
用Codex写Linux巡检脚本:AI生成,人控执行的安全实践 这周我干了一件特别纠结的事。需求本身很简单用 Codex 给一批 Linux 服务器写一套运维巡检脚本巡检项包括 CPU、内存、磁盘、时间同步、服务状态这些常规项目。真正让我纠结的是Codex 写完之后很自然地就想到要去执行命令、查看服务器状态甚至在我没有明确禁止的情况下主动提议“要不要我帮你重启一下出问题的服务”我当时愣住了。Codex 这类 AI 编程 agent能力是真强。你在终端里丢一句话它能自己读目录、查日志、写代码、跑命令甚至能把整个排查链路串起来。但“能跑命令”和“该在生产环境跑命令”完全是两码事。服务器是高价值资产AI 可以写代码、出方案、做巡检但“重启”这种行为有明确副作用影响面可能波及整条业务链路绝对不能直接交给 AI 拍板。所以这次项目我给自己定了一条铁律Codex 只负责生成和迭代巡检脚本所有脚本必须经过人工评审、静态检查、灰度执行最终由人来手动触发整个操作过程有完整审计记录。如果你也在用 Codex 这类 agent 做运维或者正打算让 AI 帮你写巡检脚本这篇文章应该能帮你在“效率”和“安全”之间找到一个平衡点。我会把整个项目从环境准备、脚本设计、Codex 协作流程到踩坑记录全部过一遍全是这周真实操作下来的东西。1. 为什么我坚决不让 AI 直接动生产服务器先说结论AI 生成代码的能力远大于 AI 做生产决策的能力。理解这个差异你就理解了整个项目的边界。1.1 AI 真正擅长的是生成而不是决策Codex 底层的语言模型是概率模型每次输出都是基于上下文预测出的“最像样”的下一步。它写代码非常厉害因为它见过的开源仓库足够多能模仿出接近人类的工程结构。但生产环境的决策不一样一台服务器上跑着哪个业务、哪个进程的优先级最高、哪个服务挂了会牵连什么下游系统这些隐含的依赖关系模型是看不到的。我见过一个真实的例子。有同事让 AI 排查一台机器负载过高的问题AI 在终端里查了一圈发现某个 Java 进程占用 CPU 很高然后直接建议 kill 掉这个进程。从“查找高占用进程”的角度这个建议完全正确。但那台机器跑的是核心交易系统的支付回调服务kill 掉意味着线上大量订单回调失败。AI 不知道这些它只看到 CPU 和进程名。这个例子特别典型。AI 可以看到 syslog、可以看 /proc、可以执行 top但它理解不了“为什么这个进程不能杀”。生产系统里大量的知识是隐性的存在于运维脑子里的业务拓扑、工单记录、告警历史里模型训练数据里没有这些。1.2 生产环境的最小动作原则运维这行有一个不成文的原则生产环境做任何操作都要先回答三个问题——这次操作的爆炸半径有多大能不能回滚有没有审计记录把这三个问题套在“AI 直接执行命令”上你会发现基本不合格。语言模型生成的命令是不可完全预测的同样的 Prompt 在两次执行中可能产生不同结果代理工具还可能在对话过程中自行组合多条命令造成连锁动作。爆炸半径完全不可控。更关键的是审计现在主流的 AI agent 虽然会打印执行过程但日志格式五花八门缺少标准的操作时间、操作人、审批人、变更原因字段很难满足企业内部的变更管理要求。所以我坚持一个做法人机闭环。AI 负责产出脚本、生成方案、写文档人负责评审、批准、执行。注意这不是不信任 AI而是把 AI 放在它最擅长的“生成”环节把人放在最需要判断力的“执行”环节。两个角色各司其职效率和安全都能兼顾。1.3 巡检脚本是 AI 辅助运维的最佳切入点那为什么说巡检脚本特别适合交给 AI因为它同时满足三个条件只读操作、幂等执行、低风险输出。只读意味着脚本不会修改系统状态它只是收集数据。幂等意味着同一个脚本跑一百遍结果应该一致不会因为重复执行产生副作用。低风险意味着即便脚本写错了最坏的情况是漏报或者误报顶多多看一眼告警不会把业务搞挂。这跟“重启服务器”形成鲜明对比。重启是有副作用的、不可逆的、影响面取决于业务拓扑的操作属于高风险变更。巡检则是典型的安全操作。既然安全我们就可以放心地把 Codex 的输出范围圈定在“生成巡检脚本”上然后在人工审核后投入生产使用。2. 先把 Codex 环境跑通安装、配置与模型接入想在项目里真刀真枪用 Codex第一步不是写 Prompt而是把环境配好。我建议在本地开发机或者跳板机上装别直接装在堡垒机和生产机器上后续你会上 Gradle 踩坑的。2.1 Codex 的安装与初始化Codex 目前通过 Node.js 生态分发最直接的安装方式是 npm 全局安装macOS 用户也可以用 Homebrew。我这边用的是 npm 方式流程如下。# 先确认 Node 版本建议 22 以上 node -v # 安装 Codex CLI npm install -g openai/codex # 确认安装成功 codex --version安装完成后第一次启动会进入初始化流程它会询问你使用哪种登录方式、选择模型服务提供商。这里有个小坑如果终端代理或者网络环境有问题初始化可能一直卡住报一些类似“connection failed”的错误。这种时候别急着折腾网络先检查两样东西一是系统的时钟是否准确二是环境变量里有没有遗留的 HTTP_PROXY、HTTPS_PROXY 配置。时钟偏移和冲突的代理配置是 agent 工具连不上服务的两个最常见原因。2.2 把 Codex 接到更顺手的模型服务Codex 底层设计成了“模型可替换”官方模型之外也支持各种兼容 OpenAI API 格式的服务商。国内团队普遍的操作是把它接到国内合规的大模型服务上比如 DeepSeek 这类提供 OpenAI 兼容接口的厂商。好处是网络稳定、计费灵活而且模型的中文理解能力也不错特别适合中文需求描述。配置方式很简单通过环境变量指定接口地址、模型名称和 API Key 即可。export OPENAI_BASE_URLhttps://api.example.com/v1 export OPENAI_API_KEY你的API密钥 export OPENAI_MODELdeepseek-chat也可以把配置写进 Codex 的配置文件项目目录下创建.codex/config.toml内容大概是这个样子。model deepseek-chat model_provider deepseek [model_providers.deepseek] name DeepSeek 兼容接口 base_url https://api.example.com/v1 env_key OPENAI_API_KEY注意 base_url 必须指向服务商提供的 OpenAI 兼容地址不同服务商路径前缀略有差异有的是 /v1有的是 /api/v1配好后用codex --version跑一次简单对话验证即可。2.3 工作模式与安全边界设置Codex 在终端里提供几种工作模式核心是 Chat、Exec 和 Apply 三类。Chat 模式只做对话模型不会执行任何命令适合讨论方案。Exec 模式会允许模型在沙箱里执行命令适合让它自动完成开发任务。Apply 模式则会把模型给出的修改写入文件适合代码生成。我的建议是在“AI 辅助运维巡检”这个场景下使用 Chat 或 Apply 模式来生成脚本不要开启 Exec 模式去让它在服务器上自由执行命令。如果一定要用 Exec 模式也必须在专门的测试环境、非生产环境里进行并且严格控制工作目录。另外绝对不要用 root 身份运行 Codex这是底线。想象一下一个写代码很厉害但不懂业务依赖的实习生配上 root 权限会发生什么。注意Codex 的工作目录就是它的“活动范围”。把它的工作目录指到一个新建的空项目目录避免它扫到服务器上其他敏感的配置文件。3. 交给 Codex 前先想清楚巡检脚本的“可审计”设计很多人在用 AI 写脚本时上来就丢一句“帮我写个巡检脚本”然后得到一个看起来挺完整但完全不可用的玩意儿。问题不在 AI而在需求太模糊。尤其是“可审计”这个要求必须在设计阶段就画进架构里。3.1 “可审计”到底审计什么可审计包含三个层次操作可见、状态可复盘、结果可追溯。操作可见是所有脚本的命令和参数都要在日志里清晰记录执行者能看出每一步在干什么。状态可复盘是每次执行的时间、主机、结果都要留存出了问题能回看当时环境长什么样。结果可追溯是脚本本身要有版本号、哈希值能确认“导到生产上跑的确实是评审过的那一版”。对应到脚本设计上至少要满足这几个硬性要求脚本输出结构化数据比如 JSON而不是一堆 grep 出来的文本。所有输出文件带主机名和时间戳防止多台机器互相覆盖。脚本内置版本号和哈希自校验逻辑启动时先确认文件没有被篡改。执行全程记录日志日志文件放在独立目录不跟业务日志混在一起。3.2 巡检项怎么定从系统层到业务层巡检脚本的价值完全体现在巡检项的设计上项目越多越全面但并不代表越多越好。巡检项太少会漏问题太多会制造噪音关键是覆盖到真正会“突然出大事”的维度。我这次让 Codex 覆盖的巡检项大致是下面这些正好覆盖了服务器运维最核心的几个隐患点。分类巡检项关键命令/查询方式默认告警阈值CPU平均负载、使用率uptime、/proc/loadavg15分钟负载持续高于核数 x 0.7内存总量、已用、Swapfree -m可用内存低于 20% 或 Swap 持续增长磁盘空间使用率、inodedf -h、df -i使用率大于 85%inode 大于 90%RAID阵列状态mdadm --detail、storcli出现 Degraded 或 Failed 即 Critical时间同步NTP/chrony 状态与偏移chronyc tracking、ntpq -poffset 大于 500ms服务关键服务存活systemctl is-active非 active 状态即 Critical端口监听端口是否符合预期ss -tlnp预期端口未监听即 Critical日志系统日志中的 ERROR/panicjournalctl、grep最近 30 分钟内出现 ERROR 即告警证书业务证书剩余有效期openssl x509 -enddate剩余 30 天内 Warning7 天内 Critical进程僵尸进程数量ps aux大于 0 即 Warning这里有个容易被忽略的点时间同步。很多人不把它当回事但时钟偏移引发的连锁故障非常可怕轻则日志时间对不上重则分布式事务超时、缓存失效。巡检脚本里一定要带上 chronyd 或 ntpd 的同步状态检查offset 超过 500ms 就该告警了。另外RAID 状态检查需要根据服务器实际情况配置软件 RAID 用 mdadm硬件 RAID 可能要依赖厂商的 storcli 或 megacli 工具。让 Codex 生成脚本时它通常不认识你是哪种 RAID 卡所以生成完以后人工评审时必须确认这些命令在当前机器上真实存在。3.3 给 Codex 写一份高质量需求单给 Codex 的需求描述本质上就是一份“给实习生的详细任务书”。写得好不好直接决定生成脚本的质量。我这次实际使用的 Prompt 模板大概是这样你是一位资深运维工程师。请帮我写一个只读的 Linux 服务器巡检脚本。 背景要求 1. 使用 bash兼容 CentOS 7 / Ubuntu 20.04 等主流发行版尽量不依赖额外安装的工具。 2. 脚本只能做信息收集禁止任何修改、删除、重启、安装、卸载操作。 3. 巡检项包括CPU负载与使用率、内存与Swap、磁盘空间与inode、RAID阵列状态、时间同步偏移、关键服务存活状态、监听端口、主要系统日志错误、证书有效期、僵尸进程数量。 4. 输出为 JSON 格式文件名为 hostname_YYYYmmdd_HHMMSS.json字段包含 hostname、timestamp、脚本版本号、items每项带 status 和 detail。 5. 阈值通过环境变量或脚本参数注入不写死提供默认值。 6. 所有外部命令执行都要有超时保护超过 10 秒自动跳过并在结果中标记为 skipped。 7. 脚本必须幂等可重复执行且不产生任何副作用。 8. 关键服务列表和证书路径需要提前定义成变量方便我按集群修改。 9. 脚本本身必须包含版本号变量执行时输出。这个需求单看着很长但每条都是在给 AI 划安全边界。特别是“只读”和“幂等”这两条必须写得清清楚楚。如果只写“帮我写个巡检脚本”Codex 很容易自由发挥加一些自动清理、自动重启的“贴心”逻辑那就是灾难。3.4 阈值设计为什么不能一把梭巡检脚本最容易出问题的地方就是阈值定得太死。CPU 使用率超过 80% 就报警对高并发的 Web 服务器来说可能天天误报对只有 2 核的小机器来说80% 可能已经快撑不住了。我的建议是阈值必须参数化。Codex 生成的脚本里阈值不要写死而是从环境变量或配置文件读取并提供合理的默认值。举个例子磁盘使用率默认 85%但如果这台机器是数据库服务器我会把阈值调到 70%看的是业务差异。另外负载阈值的设定要跟 CPU 核数挂钩。判断规则应该是“负载是否持续高于核数乘以某个系数”而不是简单对比一个固定数字。你可以让 Codex 用nproc自动读取核数再把阈值按比例算出来这样脚本在同集群的不同配置机器上都能跑。# 示例负载阈值根据核数自适应 CPU_CORES$(nproc) LOAD_THRESHOLD$(echo $CPU_CORES * 0.7 | bc)4. 与 Codex 协作从生成脚本到评审落地需求单写好了接下来就是真正跟 Codex 打交道。这部分我讲讲实际操作流程不是那种“一步到位”的营销话术而是多轮沟通、持续打磨的真实过程。4.1 第一轮生成拿到可评审的初稿我把上面那段需求单直接贴给 Codex让它生成脚本。Codex 返回了一段大约 150 行的 bash 脚本整体结构是能用的顶部定义了主机名、时间戳、输出目录中间按巡检项分成了函数最后汇总成 JSON 写入文件。但它生成的脚本存在几个典型问题。第一个它默认使用了jq来组装 JSON可我目标服务器上大概率没装 jq这个依赖必须去掉。第二个它检查 RAID 状态时直接调用了storcli命令但部分服务器是软件 RAID根本不认识这个命令需要改成动态探测。第三个它的超时保护只在部分命令上生效ping 和证书检查没有包 timeout。第一轮评审结果脚本骨架合格具体实现问题不少。这也印证了一件事把 Codex 当成“能在几分钟内写出初稿的高级工程师”可以但不能把它当成“写完就能直接上线”的交付方。4.2 追问与修正让脚本带上自保护机制第一轮审完我开始给 Codex 提修改意见。这一步用“追问”的方式逐条把问题讲清楚。我发的修改要求大致是“请把 jq 依赖去掉用纯 bash 字符串拼接或 awk 生成 JSONRAID 检测需要先判断是软件 RAID 还是硬件 RAID动态选择 mdadm 或 storcli所有命令统一用 timeout 10s 包裹脚本顶部增加 set -uo pipefail并且输出目录不存在时自动创建每个采集函数需要捕获失败失败时写 statusfailed而不是让整个脚本中断。”Codex 会基于这些要求重新输出修改后的脚本。因为需求单本身写得足够细它改起来基本不会跑偏。我再花十分钟把改完的脚本读一遍重点看两点它有没有把超时和错误处理真的加到所有命令上以及 JSON 生成逻辑在没有 jq 的情况下是否可靠。这轮修正完脚本基本能看了。我让 Codex 再做了一件事给脚本加上--dry-run参数开启后只打印将要执行的命令不真正采集数据。这个参数看起来小但在评审环节价值巨大评审人可以快速扫描“这个脚本到底想对我的服务器做什么”。4.3 静态检查与灰度验证脚本定稿后我不会直接丢到生产服务器上跑。先静态检查实在一点# 语法检查 bash -n check_server.sh # shellcheck 静态分析能发现大量隐患 shellcheck check_server.shshellcheck 是必跑项它会报出未加引号的变量、可能的路径解析问题、不兼容的语法等等。Codex 生成的脚本一般不会有大语法错误但 shellcheck 能在“逻辑安全”层面帮你筛掉很多低级坑比如rm -rf后面跟了没校验的变量。静态检查通过后先在测试环境跑一遍确认输出目录、JSON 格式、阈值判断都正常。然后再到生产环境挑一台非核心的机器比如某个低优先级的日志服务器手动执行一次观察监控平台的曲线有没有异常。实操心得第一次在生产环境跑新脚本我习惯用bash -x加上--dry-run一起跑可以看到每一步实际执行了什么方便核对路径。确认无误后再关掉 -x 正式执行。4.4 把脚本纳入版本管理巡检脚本不是一次性产物它会被长期维护。所以完成验证后我立刻把它纳入了 Git 仓库项目结构大概是这样的。ops-inspection/ ├── check_server.sh # 主巡检脚本 ├── config/ │ ├── thresholds.env # 阈值配置 │ └── services.env # 各集群关键服务列表 ├── reports/ │ └── 2025-01-15/ # 按日期存放巡检结果 ├── README.md # 使用文档 └── CHANGELOG.md # 脚本变更记录Git 的好处不只是版本控制它能保证你随时能 diff 出“这个脚本从 v1.2 到 v1.3 到底改了什么”。出了事故你能追溯到具体是哪一行命令、哪一次变更引入的问题。这就是可审计的落地表现。5. 踩坑实录Codex 写运维脚本时的常见问题用 Codex 写运维脚本这几天我踩了不少坑有些是 AI 工具的共性有些是运维场景特有的。整理在这给你当参考。5.1 AI 一本正经地编造路径和命令这是最典型的问题。Codex 在生成脚本时会基于训练数据里的经验“猜”路径猜错的时候毫不含糊。比如它把日志路径/opt/app/logs写成/var/log/opt-app把 systemd 服务名nginx写成nginxd。如果我直接拿去生产跑可能会因为日志路径不存在而漏报或者因为服务名错误而误报。对策是两层。第一在需求单里明确要求“所有路径和服务名必须使用变量集中配置”不给它写死的机会。第二人工评审时绝对不能跳脚本要逐行核对每个路径、每个服务名。你也可以让 Codex 在脚本开头加一个环境探测函数自动检查这些路径和服务是否存在不存在就直接报错退出而不是带病执行。5.2 危险命令黑名单审查Codex 生成的脚本默认不会写rm -rf但如果你在对话中说了一句“顺便把临时文件清理掉”它可能就在某个函数里加了rm -rf $TMP_DIR。这就是我前面强调“禁止修改”要写进需求单的原因。我自己的习惯是每次 Codex 生成完脚本第一件事就是跑一条危险命令扫描grep -nE rm -rf|reboot|shutdown|systemctl restart|systemctl stop|mkfs|dd if|iptables|userdel|kill -9 check_server.sh命中一个就回到对话里明确告诉 Codex“不允许出现清理、重启、停止任何服务的逻辑。”AI 需要强约束你越宽容它越容易自由发挥。5.3 SSH 批量执行时环境变量与 locale 的坑巡检脚本要跑在多台服务器上常见做法是通过 SSH 批量分发执行。Codex 生成的批量执行脚本里有一个隐患SSH 远程执行时非交互式 shell 不会加载用户的 .bashrc导致一些环境变量和 PATH 跟本地不一样。比如把脚本分发到目标机后发现python找不到、systemctl不在 PATH 里。解决方案是在远端执行时显式用绝对路径或者先加载环境ssh roothost source /etc/profile /opt/scripts/check_server.sh还有一个经常被忽略的坑是 locale。某些服务器的 LANG 是空的shell 脚本里用到中文注释或中文输出时可能报Illegal byte sequence错误。最稳妥的做法是脚本开头固定设置一个安全的 localeexport LC_ALLen_US.UTF-85.4 并发执行与告警风暴巡检脚本一旦要在几十台服务器上同时跑就要考虑并发量。Codex 生成的批量脚本往往会用最简单的for循环加后台执行几台没问题几十台同时跑SSH 连接风暴、监控平台告警风暴分分钟把运维群炸了。我让 Codex 在批量执行脚本里增加并发控制比如用xargs -P指定并发数默认 5并给每台机器的 SSH 连接加超时# 并发 5 台执行巡检 cat server_list.txt | xargs -P 5 -I {} ssh -o ConnectTimeout5 {} /opt/scripts/check_server.sh跑完之后所有主机的结果文件不要写到同一个共享目录里否则同名文件会互相覆盖。每台机器的输出文件一定要带独立的主机名前缀这也呼应了前面说的可审计要求。5.5 过度设计警惕 AI 的“自动修复”Codex 还有个特点如果需求里没说“不要修复”它很容易给脚本加上“发现问题自动处理”的逻辑。比如磁盘满了帮你清空 /tmp服务挂了帮你 systemctl restart端口不通帮你重新加载防火墙。单看每一条都挺合理但组合在一起就是一台自动操作的生产炸弹。我的原则是巡检脚本只负责发现问题、记录问题、上报问题永远不要处理问题。发现问题之后人在哪里在工单系统里、在告警群里、在决策流程中。自动化巡检的目的是让人更快发现问题而不是替代人去决策。6. 最终工作流AI 只收拾情报人负责扣扳机项目收尾的时候我把整套流程固化了下来现在每天按这套方式运行。6.1 巡检数据归集与报告生成每台服务器跑完巡检会生成一个 JSON 文件。我让 Codex 额外写了一个汇总脚本把指定目录下所有主机的 JSON 汇总成一个总表输出成 Markdown 格式的日报。汇总表会列出每台主机的各项 statusWarning 和 Critical 的项会被挑出来直接推到团队群里。这一步用 webhook 就能实现不需要引入额外的监控系统。信息流转路径就是这么简单巡检脚本采集 - JSON 落地 - 汇总脚本生成报告 - 推送到消息群。全链路都是 code都放在同一个 Git 仓库里任何人随时可以审计。6.2 周期执行与监控联动巡检脚本不是跑一次就完事。我现在用 cron 计划任务每天凌晨 2 点跑全量巡检白天高峰期每 15 分钟只跑一个轻量模式只查 CPU、磁盘、端口和关键服务这种最可能突然出事的项目。轻量模式输出到独立的 quick_report 文件避免跟全量巡检的结果混在一起。另外想强调一点这类脚本巡检和监控平台不是替代关系。Prometheus、Grafana 适合做指标趋势和告警而脚本巡检适合做“深挖型”检查比如证书过期时间、RAID 阵列状态、时间同步偏移这些监控平台不一定能直接覆盖到的维度。两者配合才算完整的巡检体系。6.3 我现在的习惯说点个人的体会。这周跟 Codex 配合下来最大的感受是AI 确实能大幅提升效率过去写一套这种规模的巡检脚本从设计到调通可能要一两天这回基本半天就完成了初版。但效率提升的前提是我把安全边界划得很清楚它写它的我审我的任何一行可能产生副作用的命令都不允许出现。我现在养成了一个习惯每次让 Codex 改完脚本都要求它用一段话说明“改动点和影响面”再配合 git diff 做人工核对。这样即使改坏了也随时能回退。你也别嫌麻烦AI 生成代码的能力越强人在安全和审计上的控制就越重要。把 AI 当成一个技术很强的实习生方案可以大胆出但最终拍板和按回车的一定是你。