Linux运维脚本需捕获真实错误上下文而非堆栈:重定向stderr、启用set -euo pipefail、显式检查命令、记录时间戳+行号+上下文、模拟cron环境、固化工作目录、使用绝对路径、附带证据链上报。

Linux运维脚本本身不产生“堆叠错误”——这是程序崩溃时的内存调用栈(backtrace),而Shell脚本是解释执行的,不会像C/C++那样触发段错误并生成完整堆栈。你真正需要捕获的,是定时任务执行过程中暴露的错误上下文:命令失败位置、报错行号、stderr输出、环境缺失线索。这些信息比“堆栈”更关键、更可操作。
捕获真实错误来源:重定向+显式判断
crontab默认只捕获stdout,所有关键报错(ModuleNotFoundError、Permission denied、command not found)都走stderr,不重定向就彻底丢失。
- 在crontab中强制合并输出:
0 2 * * * /path/to/backup.sh >> /var/log/backup.log 2>&1 - 脚本开头加
set -euo pipefail,让任意命令失败立即终止,避免错误被吞掉 - 对关键步骤做显式检查:
tar -cf backup.tar /data || { echo "ERROR at line $LINENO: tar failed" >&2; exit 1; }
让每条错误自带定位信息:时间戳+行号+上下文
光有报错文本不够,得知道“谁、在哪儿、什么时候、干了什么失败了”。
- 定义统一日志函数:
log_err() { echo "[$(date -u '+%F %T')] [ERR] $(basename $0):$LINENO — $*" >&2; } - 用
trap 'log_err "Script interrupted"; exit $?' INT TERM捕获中断信号 - 用
trap 'log_err "Unexpected error on line $LINENO, exit code $?"' ERR自动记录任意命令失败点
模拟cron真实环境,提前暴露问题
手动执行成功 ≠ cron能跑通。cron用/bin/sh、极简PATH、无TTY、无profile加载。
- 测试命令必须这样写:
sudo -u backup env -i PATH=/usr/bin:/bin /bin/sh -c '/path/to/script.sh' - 脚本开头主动固化工作目录:
cd "$(dirname "$0")" || { log_err "Cannot cd to script dir"; exit 1; } - 避免
python或jq等命令,改用/usr/bin/python3和/usr/bin/jq绝对路径
错误上报不靠运气,要带证据链
失败后仅发一封“备份失败”邮件毫无价值。必须附带可复现的最小证据。
- 上报内容至少含:主机名、脚本路径、错误发生行号、前10行stderr(
2>&1 | head -n 10) - 优先用
mail -s "FAIL $(hostname) $(date -I)" admin@example.com,兼容性最强 - 若用微信/钉钉,用
curl -m 5 --retry 2调Webhook,超时和重试必须显式控制


















