🐍 用Python写CLI工具:从脚本到企业级运维利器的实战指南
在企业IT运维中,CLI工具是连接人与系统的桥梁。无论是批量部署、日志分析,还是自动化巡检,一个健壮的CLI工具能大幅提升效率。今天,我们不聊花哨的框架,而是聚焦如何用Python打造一个可维护、可扩展、生产级CLI工具,并给出可直接落地的代码与配置。
为什么选择Python写CLI?
• 低门槛:Python语法简洁,运维人员无需C/Go背景即可快速上手。
•生态丰富:argparse、click、typer等库原生支持CLI,subprocess和paramiko可轻松调用系统命令或远程操作。
• 跨平台:Windows/Linux/macOS统一运行,减少环境适配成本。
实战:构建一个“服务健康检查”CLI工具
我们将实现一个名为 svc-check 的工具,支持以下功能:
1. 检查本地/远程服务的进程状态(如nginx、mysql)。
2. 支持输出JSON格式(便于对接监控系统)。
3. 支持超时控制和错误重试。
第一步:项目结构
svc-check/
├── svc_check.py # 主入口
├── requirements.txt # 依赖
└── config.yaml # 服务列表配置
第二步:核心代码实现
svc_check.py(使用argparse和yaml):
#!/usr/bin/env python3
import argparse
import yaml
import subprocess
import json
import sys
import time
from typing import Dict, List
def load_config(config_path: str) -> Dict:
"""加载YAML配置文件"""
with open(config_path, 'r') as f:
return yaml.safe_load(f)
def check_service(service_name: str, cmd: str, timeout: int = 5, retries: int = 1) -> Dict:
"""执行系统命令检查服务状态"""
result = {"name": service_name, "status": "unknown", "output": ""}
for attempt in range(retries + 1):
try:
out = subprocess.run(
cmd, shell=True, capture_output=True, text=True, timeout=timeout
)
if out.returncode == 0:
result["status"] = "running"
result["output"] = out.stdout.strip()
break
else:
result["output"] = out.stderr.strip()
if attempt < retries:
time.sleep(1) # 重试间隔
except subprocess.TimeoutExpired:
result["output"] = f"Timeout after {timeout}s"
break
return result
def main():
parser = argparse.ArgumentParser(description="企业级服务健康检查工具")
parser.add_argument("-c", "--config", default="config.yaml", help="配置文件路径")
parser.add_argument("-s", "--service", help="指定检查单个服务(如nginx)")
parser.add_argument("--json", action="store_true", help="以JSON格式输出")
parser.add_argument("--timeout", type=int, default=5, help="单次检查超时秒数")
parser.add_argument("--retries", type=int, default=1, help="失败重试次数")
args = parser.parse_args()
# 加载配置
config = load_config(args.config)
services = config.get("services", [])
# 如果指定了单个服务,过滤列表
if args.service:
services = [s for s in services if s["name"] == args.service]
if not services:
print(f"Error: Service '{args.service}' not found in config.")
sys.exit(1)
# 执行检查
results = []
for svc in services:
# 支持自定义命令,如:pgrep -x nginx
cmd = svc.get("command", f"pgrep -x {svc['name']}")
res = check_service(svc["name"], cmd, args.timeout, args.retries)
results.append(res)
# 输出
if args.json:
print(json.dumps(results, indent=2))
else:
for r in results:
status_icon = "✅" if r["status"] == "running" else "❌"
print(f"{status_icon} {r['name']}: {r['status']}")
if r["output"]:
print(f" Output: {r['output']}")
if __name__ == "__main__":
main()
config.yaml 示例配置:
services:
- name: nginx
command: "pgrep -x nginx"
- name: mysql
command: "systemctl is-active mysql"
- name: redis
command: "redis-cli ping"
第三步:运行与测试
# 1. 安装依赖
pip install pyyaml
# 2. 检查所有服务(默认输出)
python svc_check.py
# 3. 检查单个服务,JSON输出
python svc_check.py -s nginx --json
# 4. 自定义超时与重试
python svc_check.py --timeout 3 --retries 2
输出示例(JSON模式):
[
{
"name": "nginx",
"status": "running",
"output": "1234"
},
{
"name": "mysql",
"status": "running",
"output": "active"
}
]
进阶技巧:让CLI工具更“企业级”
1. 参数化配置优于硬编码
• 使用YAML/JSON配置文件管理服务列表,避免修改代码。
• 支持环境变量覆盖(如 --timeout 可被 SVC_CHECK_TIMEOUT覆盖)。
2. 错误处理与日志
• 使用 try/except捕获 subprocess 的异常,避免脚本崩溃。
• 关键操作添加日志(推荐 logging模块),便于事后审计。
3. 输出标准化
• 提供 --json选项,方便被Prometheus、Zabbix等监控系统消费。
• 普通用户模式输出彩色Emoji或ANSI颜色,提升可读性。
4. 模块化设计
• 将检查逻辑、配置加载、输出格式化拆分为独立函数,便于单元测试。
• 支持插件式扩展(如新增“磁盘使用率检查”模块)。
避坑指南
•避免shell=True 的安全风险:如果命令参数来自用户输入,务必使用参数列表而非字符串(如 ["pgrep", "-x", name])。
•超时机制必须实现:网络或进程卡死时,subprocess.run的timeout参数是保命符。
•Windows兼容性:pgrep在Windows不存在,可替换为tasklist /FI "IMAGENAME eq nginx.exe"。
总结
用Python写CLI工具,核心是让运维同学能用最少的代码,解决最实际的问题。从argparse解析参数,到YAML管理配置,再到JSON输出对接监控,每一步都服务于“可复用、可调试、可扩展”的企业级需求。下次遇到重复性检查任务,别再用ps aux | grep了,写一个专属CLI工具,解放双手。
关注我,为您分享更多的IT知识!