Codex 实战:用 AI 写运维脚本
·
1. 引言
在日常运维工作中,脚本编写往往占据大量时间:日志分析、批量部署、故障排查、数据备份……这些任务重复且耗时。随着 AI 编程助手的发展,Codex 等工具正在改变运维工程师的工作方式——从「手写每一行代码」到「用自然语言描述需求,让 AI 生成脚本」。
本文将带你从零开始,掌握使用 Codex 编写运维脚本的完整流程,包括环境准备、提示词技巧、实战案例以及常见坑点,帮助你真正把 AI 应用到日常运维工作中。
2. Codex 简介与核心能力
2.1 什么是 Codex
Codex 是 OpenAI 推出的 AI 编程助手,能够理解自然语言指令并生成、修改、解释代码。它基于大规模代码语料训练,支持多种编程语言,尤其擅长 Python、Bash、PowerShell 等运维常用语言。
2.2 核心能力
- 代码生成:根据自然语言描述生成完整脚本
- 代码解释:分析现有脚本的逻辑与作用
- 代码优化:重构冗余代码,提升执行效率
- 错误修复:定位并修复脚本中的 Bug
- 多语言支持:Python、Bash、PowerShell、Go 等
2.3 适用场景
- 日志分析与统计
- 批量文件处理与备份
- 系统监控与告警
- 自动化部署与配置
- 故障排查与诊断
3. 环境准备与接入方式
3.1 接入方式对比
| 接入方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 官方 Web 界面 | 日常交互式提问 | 无需配置,开箱即用 | 无法集成到自动化流程 |
| API 调用 | 集成到自研工具 | 可编程控制,支持批量 | 需要 API Key,有费用 |
| 命令行工具 | 本地开发环境 | 与终端工作流无缝衔接 | 需要安装配置 |
| IDE 插件 | 开发调试阶段 | 上下文感知,实时补全 | 依赖 IDE 环境 |
3.2 环境准备清单
- 注册 OpenAI 账号并获取 API Key
- 安装 Python 3.8+ 环境
- 安装 Codex CLI 工具(如适用)
- 配置网络代理(如需要)
3.3 快速验证
# 安装 Codex CLI(示例)
pip install codex-cli
# 验证是否安装成功
codex --version
4. 编写高效提示词的核心技巧
4.1 提示词五要素
一个高质量的运维脚本提示词,通常包含以下五个要素:
- 角色设定:明确 Codex 扮演的角色
- 任务描述:清晰说明要完成的任务
- 输入输出:指定输入数据格式和期望输出
- 约束条件:说明运行环境、依赖、性能要求
- 示例参考:提供输入输出示例帮助理解
4.2 提示词模板
你是一位资深运维工程师,请帮我编写一个 Python 脚本。
任务:分析 Nginx 访问日志,统计每个 IP 的访问次数,并输出 Top 10。
输入:/var/log/nginx/access.log,每行格式为:
$remote_addr - - [$time_local] "$request" $status $body_bytes_sent
输出:按访问次数降序排列的 IP 列表,格式为:
IP地址 访问次数
约束:
- 使用 Python 3,仅依赖标准库
- 日志文件可能很大,需考虑内存优化
- 输出结果保存到 result.txt
4.3 常见误区
- 描述过于笼统:只说「写个监控脚本」,没有明确监控对象和告警方式
- 忽略边界情况:未说明文件不存在、格式异常等情况的处理
- 缺少验证标准:没有定义「脚本正确」的验收标准
5. 实战案例一:日志分析脚本
5.1 需求描述
编写一个 Python 脚本,分析 Web 服务器访问日志,统计各状态码(200、404、500 等)的出现次数,并输出占比最高的前 5 个状态码。
5.2 提示词示例
请编写一个 Python 脚本 analyze_log.py,功能如下:
1. 读取指定日志文件(通过命令行参数传入路径)
2. 使用正则表达式提取每行中的 HTTP 状态码
3. 统计各状态码出现次数
4. 输出占比最高的前 5 个状态码及其占比(保留两位小数)
5. 如果文件不存在,打印友好错误信息并退出
示例日志行:
192.168.1.1 - - [05/Sep/2026:10:30:00 +0800] "GET /index.html HTTP/1.1" 200 1024
5.3 生成结果示例
#!/usr/bin/env python3
"""分析 Web 访问日志中的 HTTP 状态码分布。"""
import re
import sys
from collections import Counter
def analyze_log(filepath: str) -> None:
"""读取日志文件并统计状态码分布。"""
pattern = re.compile(r'"\w+\s+\S+\s+HTTP/\d\.\d"\s+(\d{3})')
status_counter = Counter()
try:
with open(filepath, "r", encoding="utf-8") as f:
for line in f:
match = pattern.search(line)
if match:
status_counter[match.group(1)] += 1
except FileNotFoundError:
print(f"错误:文件 {filepath} 不存在", file=sys.stderr)
sys.exit(1)
total = sum(status_counter.values())
if total == 0:
print("未找到有效的状态码记录")
return
print(f"{'状态码':<8}{'次数':<8}{'占比':<8}")
print("-" * 24)
for status, count in status_counter.most_common(5):
percent = count / total * 100
print(f"{status:<8}{count:<8}{percent:.2f}%")
if __name__ == "__main__":
if len(sys.argv) != 2:
print("用法:python analyze_log.py <日志文件路径>")
sys.exit(1)
analyze_log(sys.argv[1])
5.4 验证与优化
- 用真实日志样本测试脚本输出
- 检查边界情况:空文件、超大文件、异常格式
- 根据实际需求调整 Top N 数量或输出格式
6. 实战案例二:批量服务器状态检查
6.1 需求描述
编写一个 Bash 脚本,批量检查多台服务器的 CPU、内存、磁盘使用率,并将结果汇总输出。
6.2 提示词示例
请编写一个 Bash 脚本 check_servers.sh,功能如下:
1. 从 servers.txt 文件中读取服务器列表(每行一个 IP 或主机名)
2. 通过 SSH 连接每台服务器,执行以下命令:
- CPU 使用率:top -bn1 | grep "Cpu(s)"
- 内存使用率:free -m
- 磁盘使用率:df -h /
3. 将每台服务器的检查结果汇总,以表格形式输出
4. 支持通过 -u 参数指定 SSH 用户名
5. 某台服务器连接失败时,跳过并记录错误,不中断整个脚本
6.3 生成结果示例
#!/bin/bash
# 批量检查服务器资源使用情况
USERNAME="root"
SERVERS_FILE="servers.txt"
# 解析参数
while getopts "u:" opt; do
case $opt in
u) USERNAME="$OPTARG" ;;
*) echo "用法:$0 [-u 用户名]"; exit 1 ;;
esac
done
if [ ! -f "$SERVERS_FILE" ]; then
echo "错误:找不到服务器列表文件 $SERVERS_FILE"
exit 1
fi
echo "开始检查服务器状态..."
echo "=========================================="
while IFS= read -r server; do
[ -z "$server" ] && continue
echo ">>> 正在检查 $server ..."
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$USERNAME@$server" \
"echo '--- CPU ---'; top -bn1 | grep 'Cpu(s)'; \
echo '--- 内存 ---'; free -m | grep Mem; \
echo '--- 磁盘 ---'; df -h / | tail -1" 2>/dev/null; then
echo ">>> $server 检查完成"
else
echo ">>> $server 连接失败,已跳过" >&2
fi
echo "------------------------------------------"
done < "$SERVERS_FILE"
echo "全部检查完成。"
6.4 安全注意事项
- 建议使用 SSH 密钥认证而非密码
- 限制脚本执行权限,避免敏感信息泄露
- 生产环境建议增加超时与重试机制
7. 实战案例三:自动化备份脚本
7.1 需求描述
编写一个 Python 脚本,将指定目录打包压缩,并上传到远程备份服务器,同时保留最近 7 天的备份。
7.2 提示词示例
请编写一个 Python 脚本 backup.py,功能如下:
1. 接收两个参数:源目录路径、备份服务器地址
2. 将源目录打包为 tar.gz 格式,文件名包含日期(如 backup_20260905.tar.gz)
3. 通过 scp 上传到备份服务器的 /backup 目录
4. 上传成功后,删除本地超过 7 天的旧备份文件
5. 使用 logging 模块记录执行日志,包括开始、成功、失败信息
6. 任何步骤失败时,记录错误并以非零状态码退出
7.3 生成结果示例
#!/usr/bin/env python3
"""自动化目录备份脚本:打包、上传、清理旧备份。"""
import argparse
import logging
import os
import subprocess
import sys
from datetime import datetime, timedelta
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
logger = logging.getLogger(__name__)
BACKUP_DIR = "/backup"
RETENTION_DAYS = 7
def create_archive(source_dir: str) -> str:
"""将源目录打包为 tar.gz,返回文件名。"""
date_str = datetime.now().strftime("%Y%m%d")
archive_name = f"backup_{date_str}.tar.gz"
logger.info("开始打包 %s -> %s", source_dir, archive_name)
result = subprocess.run(
["tar", "-czf", archive_name, "-C", os.path.dirname(source_dir),
os.path.basename(source_dir)],
capture_output=True,
text=True,
)
if result.returncode != 0:
logger.error("打包失败:%s", result.stderr)
sys.exit(1)
logger.info("打包完成:%s", archive_name)
return archive_name
def upload_archive(archive_name: str, remote_host: str) -> None:
"""通过 scp 上传备份文件到远程服务器。"""
logger.info("上传 %s 到 %s:%s", archive_name, remote_host, BACKUP_DIR)
result = subprocess.run(
["scp", archive_name, f"{remote_host}:{BACKUP_DIR}/"],
capture_output=True,
text=True,
)
if result.returncode != 0:
logger.error("上传失败:%s", result.stderr)
sys.exit(1)
logger.info("上传成功")
def cleanup_old_backups() -> None:
"""删除本地超过保留天数的旧备份文件。"""
cutoff = datetime.now() - timedelta(days=RETENTION_DAYS)
for filename in os.listdir("."):
if not filename.startswith("backup_") or not filename.endswith(".tar.gz"):
continue
filepath = os.path.join(".", filename)
mtime = datetime.fromtimestamp(os.path.getmtime(filepath))
if mtime < cutoff:
os.remove(filepath)
logger.info("已删除旧备份:%s", filename)
def main() -> None:
parser = argparse.ArgumentParser(description="自动化备份脚本")
parser.add_argument("source_dir", help="要备份的源目录")
parser.add_argument("remote_host", help="备份服务器地址")
args = parser.parse_args()
if not os.path.isdir(args.source_dir):
logger.error("源目录不存在:%s", args.source_dir)
sys.exit(1)
archive_name = create_archive(args.source_dir)
upload_archive(archive_name, args.remote_host)
cleanup_old_backups()
logger.info("备份流程全部完成")
if __name__ == "__main__":
main()
7.4 扩展建议
- 增加加密功能,保护敏感数据
- 接入定时任务(cron),实现全自动备份
- 增加备份完整性校验(MD5/SHA256)
8. 常见问题与调试技巧
8.1 生成脚本不满足需求怎么办
- 补充细节:提供更具体的输入输出示例
- 分步提问:将复杂任务拆解为多个小任务逐步生成
- 要求重构:明确要求「用更简洁的方式重写」「增加错误处理」
8.2 脚本运行报错如何排查
- 将报错信息完整复制给 Codex,要求解释原因
- 提供脚本上下文,要求定位问题行
- 要求生成测试用例验证关键逻辑
8.3 安全与合规注意事项
- 不要在提示词中包含敏感信息(密码、密钥、Token)
- 生成脚本涉及生产环境操作时,先在测试环境验证
- 对 AI 生成的脚本进行人工审查后再上线
9. 总结与进阶建议
9.1 核心要点回顾
- 明确需求是高效使用 Codex 的前提
- 提示词越具体,生成结果越符合预期
- AI 生成脚本仍需人工验证与优化
- 将常用提示词沉淀为模板,提升复用效率
9.2 进阶学习方向
- 学习 Codex API 集成,构建自动化运维工具链
- 结合 CI/CD 流程,实现脚本自动生成与测试
- 探索多 Agent 协作,处理更复杂的运维场景
9.3 实践建议
从今天开始,选择一个你日常最耗时的运维任务,尝试用 Codex 生成第一版脚本。在实践中积累提示词经验,逐步建立自己的「AI 运维脚本库」,让重复性工作真正自动化起来。
更多推荐


所有评论(0)