优先选bash,因其零开销、无依赖、系统自带,适合调用df/ps/systemctl等命令;python仅在需解析json、调用api或结构化输出时使用。

巡检脚本该用 bash 还是 Python?
优先选 bash,除非你要解析 JSON、调用 API 或做复杂状态聚合。Linux 巡检本质是串起 df、ps、systemctl、journalctl 这些命令,bash 直接调用零开销、无依赖、所有机器都自带。Python 一旦涉及 subprocess 调命令,还要处理编码、空格、换行截断,反而容易出错。
常见错误现象:python3 -c "import subprocess; subprocess.run(['df', '-h']) 输出乱码或卡住;bash 脚本里用 $(ps aux | grep nginx) 匹配到自己进程。
- 用
pgrep nginx替代ps | grep,避免误匹配 - 所有命令加
-o pid,comm,%cpu,%mem等明确字段,别依赖默认列顺序 - 日志检查用
journalctl --since "2 hours ago" -u sshd --no-pager,不用tail -n 100 /var/log/auth.log(可能被 logrotate 切走) - Python 只在需要结构化输出时介入:比如把多台机器的
df结果统一转成 CSV 或发钉钉
如何让巡检不干扰线上服务?
关键不是“少查”,而是“查得准、查得稳”。很多脚本一跑就触发 OOM killer 或拖慢磁盘 IO,问题出在没控制采样粒度和资源占用。
使用场景:每 5 分钟 cron 执行一次基础巡检,但 find /var/log -name "*.log" -size +100M 这种命令不能放进去——它会遍历整个目录树,IO 尖峰明显。
- 磁盘空间用
df -B1 / | awk 'NR==2 {print $4}',不加-h避免单位转换开销 - CPU/内存用
cat /proc/loadavg和awk '/MemAvailable/ {print $2}' /proc/meminfo,比top -bn1轻量十倍 - 服务状态用
systemctl is-active --quiet nginx,返回值判断,不打印任何输出 - 避免在巡检中执行
lsof、strace、tcpdump—— 它们本身就会改变系统行为
故障排查时怎么快速定位是配置、资源还是依赖问题?
先跑三行命令,比翻日志快:systemctl show --property=ExecMainPID,MemoryCurrent,SubState nginx、ss -tlnp | grep :80、curl -I http://localhost:80 -m 2 2>/dev/null || echo "connect failed"。这三步分别确认进程是否活着、端口是否监听、服务是否响应。
容易踩的坑:systemctl status nginx 显示 active (running),但实际 worker 进程已崩溃(只留 master);netstat -tlnp 在新系统默认没装,ss 是替代方案。
-
systemctl show比status更可靠,它读的是 systemd 内部状态,不依赖 journal 日志完整性 -
ss -tlnp的p参数需 root 权限,普通用户看不到 PID 和程序名,巡检脚本记得用sudo或改用ss -tln+ 端口匹配 -
curl -I加-m 2防止卡死,2>/dev/null屏蔽 SSL 错误等干扰信息 - 依赖检查别只看端口通不通,比如 Redis 连接池耗尽时,
telnet localhost 6379成功但业务报错,得补一句echo PING | redis-cli -n 0 --raw
日志关键词扫描为什么总漏报或误报?
因为直接 grep "ERROR" 忽略了大小写、上下文、日志格式差异。真实日志里可能是 [ERROR]、error:、level=error,甚至带时间戳前缀导致行首偏移。
性能影响:对 1GB 的 /var/log/syslog 做 grep -r "failed" /var/log,会触发大量小文件读取,IO 占用高且不准。
- 用
journalctl -p 3 --no-pager(priority 3 = err)代替文本 grep,利用 journal 的结构化索引 - 自定义日志扫描用
awk '/\[ERROR\]|error:|level=error/{print NR ": " $0}' /var/log/myapp.log,一行覆盖常见变体 - 加
-A 2 -B 1查看上下文,但仅限人工排查;自动化脚本里避免,防止输出膨胀 - 别扫全量日志,先用
find /var/log -name "*.log" -mtime -1锁定最近 24 小时文件
最麻烦的不是写脚本,是让巡检结果真正可操作:比如 “磁盘使用率 >90%” 得附上 du -sh /var/log/* | sort -hr | head -5 的前五名目录,否则运维还得再登录一遍才能删什么。









