Linux 自动化运维脚本设计模式

1次阅读

脚本启动时应首先用 id -u 判断是否为 root(即 uid=0),再检查关键路径写权限(如 test -w /var/log),对特权操作用 sudo -n systemctl reload + $? 验证,避免静默失败。

Linux 自动化运维脚本设计模式

脚本启动时怎么可靠判断当前运行用户和权限

很多自动化脚本在 root 下跑没问题,一换成普通用户就卡在文件写入或服务控制上,但错误提示往往不直接——比如 Permission denied 出现在写 /var/log/myscript.log 时,而不是开头就报错。必须在第一行就做权限兜底。

实操建议:

  • id -u 判断是否为 0,别依赖 $USERwhoami(可能被篡改或非交互 shell 下不准)
  • 检查关键路径的写权限:比如日志目录用 test -w /var/log,而不是只检查文件是否存在
  • 如果脚本需部分特权操作(如 reload systemd 服务),优先用 sudo -n systemctl reload myapp + $? 判断,避免静默失败

日志记录为什么不能只靠 echo >> file

直接追加日志看似简单,但在并发执行、重定向混乱、磁盘满等场景下极易丢日志、乱序甚至阻塞整个脚本。更麻烦的是,echo 不带时间戳、无级别、无法分离 stdout/stderr,查问题时像在翻乱码。

实操建议:

  • 统一用 logger -t "myscript" "message" 推送到 syslog,由 rsyslog/syslog-ng 统一落盘和轮转
  • 若必须写文件,用 exec >> /var/log/myscript.log 2>&1 在脚本开头重定向全部输出,并配合 date '+%F %T' 手动打点
  • 避免在循环里反复打开/关闭日志文件;一次性重定向后,所有 echo 自然进日志

定时任务里执行脚本,环境变量为啥总是不对

cron 启动的 shell 是极简环境:$PATH 通常只有 /usr/bin:/bin$HOME 可能指向 root,自定义变量、~/.bashrc 里的 alias 全部失效。常见症状是脚本里调 python3 报“command not found”,或 aws 命令找不到配置。

实操建议:

  • 在 crontab 条目里显式声明环境变量,例如:PATH=/usr/local/bin:/usr/bin:/bin HOME=/root
  • 脚本开头用 source /etc/profile && source ~/.bashrc 2>/dev/NULL || true 补环境(注意:仅限交互式 login shell 生效的配置)
  • 最稳做法:所有外部命令用绝对路径,比如 /usr/bin/python3/usr/local/bin/aws,避免 PATH 依赖

脚本退出码怎么设计才让监控系统真正有用

很多脚本习惯性用 exit 0 收尾,或者只在明显错误处 exit 1,结果 zabbixprometheus 拉取到的一直是 “0=成功”,根本分不清是真成功、跳过执行、还是半途静默失败。

实操建议:

  • 定义清晰的退出码语义:0=完全成功;1=参数错误;2=依赖服务不可达;3=数据校验失败;126-128 留给 shell 自身错误
  • 关键步骤后立刻检查 $?,不要到结尾再统一 exit;比如 curl -f http://api/health || exit 2
  • 在脚本末尾加 exit ${EXIT_CODE:-0},确保所有分支都有明确出口,避免因逻辑漏写导致默认返回上一条命令的码

真正难的不是写完一个能跑的脚本,而是它在没人盯着的时候,出问题能说清哪一步、为什么、谁该介入。环境、日志、权限、退出码——这四块没对齐,自动化就只是把人工操作藏得更深了。

text=ZqhQzanResources