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

脚本启动时怎么可靠判断当前运行用户和权限
很多自动化脚本在 root 下跑没问题,一换成普通用户就卡在文件写入或服务控制上,但错误提示往往不直接——比如 Permission denied 出现在写 /var/log/myscript.log 时,而不是开头就报错。必须在第一行就做权限兜底。
实操建议:
- 用
id -u判断是否为0,别依赖$USER或whoami(可能被篡改或非交互 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,结果 zabbix、prometheus 拉取到的一直是 “0=成功”,根本分不清是真成功、跳过执行、还是半途静默失败。
实操建议:
- 定义清晰的退出码语义:0=完全成功;1=参数错误;2=依赖服务不可达;3=数据校验失败;126-128 留给 shell 自身错误
- 关键步骤后立刻检查
$?,不要堆到结尾再统一 exit;比如curl -f http://api/health || exit 2 - 在脚本末尾加
exit ${EXIT_CODE:-0},确保所有分支都有明确出口,避免因逻辑漏写导致默认返回上一条命令的码
真正难的不是写完一个能跑的脚本,而是它在没人盯着的时候,出问题能说清哪一步、为什么、谁该介入。环境、日志、权限、退出码——这四块没对齐,自动化就只是把人工操作藏得更深了。