linux脚本健壮日志记录需选择性捕获异常、明确错误上下文、保留操作现场,核心是用set -euxo pipefail奠定防护基础,重定向stderr统一加时间戳或走syslog,显式捕获关键命令失败并记录上下文,区分日志级别,确保权限与磁盘空间。

在 Linux 脚本中实现健壮的错误日志记录,核心不是“把所有输出都塞进文件”,而是有选择地捕获异常、明确区分错误上下文、保留可追溯的操作现场。关键在于:错误发生时你知道是哪一行、哪个命令、什么输入导致失败,而不是只看到“script failed”。
用 set -euxo pipefail 奠定基础防护
这组选项是健壮脚本的“安全带”,应放在脚本开头(#!/bin/bash 之后):
- -e:任一命令非零退出即终止脚本,避免错误被忽略后继续执行
- -u:引用未定义变量时报错,防止因拼写错误或遗漏赋值引发静默故障
- -x:打印执行中的每条命令(含变量展开),调试时极有用,生产环境可按需关闭
- -o pipefail:让管道中任意命令失败都使整个管道返回失败码(默认只有最后一个命令决定结果)
示例:
#!/bin/bashset -euxo pipefail
重定向 stderr 并统一打时间戳
不要依赖 echo >> log 或临时重定向。用 exec 将整个脚本的 stderr 统一处理:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 用 exec 2>>(awk '{print strftime("%Y-%m-%d %H:%M:%S"), $0}' >> /var/log/myscript.log) 实现自动加时间戳
- 更轻量做法:用 logger 命令走系统日志,天然带时间、主机名、进程ID:exec 2> >(logger -t "myscript")
- 避免直接重定向到普通文件而无轮转——生产环境建议搭配 logrotate 或用 systemd-journald 管理
对关键命令做显式错误捕获与上下文记录
set -e 能终止脚本,但不帮你记录“为什么失败”。对高风险操作(如 curl、rsync、数据库查询),用 if 或 || 显式处理:
- 记录命令本身、退出码、关键变量值:if ! output=$(curl -s http://api.example.com/data); then echo "FAIL: curl exited with $? for URL http://api.example.com/data, env=$ENV_MODE" | tee -a /var/log/myscript.log; exit 1; fi
- 用 trap 捕获异常退出,打印最后执行的命令和行号:trap 'echo "ERROR at line $LINENO: $BASH_COMMAND" | logger -t myscript' ERR
- 敏感操作前记录意图,比如:echo "[$(date)] Deleting stale cache under $CACHE_DIR" | logger -t myscript
区分日志级别并控制输出位置
不要所有信息混在一起。用不同方式/通道分离关注点:
- INFO/DEBUG:用 echo 或 printf 到 stdout,供用户或调用方查看;生产环境可设 DEBUG=0 关闭
- WARN/ERROR:必须写入日志文件或 syslog,确保持久化;可用函数封装:log_error() { logger -t myscript -p user.err "$*"; }
- FATAL:记录错误 + 清理资源(如临时文件、锁)+ exit 非零码;避免残留状态影响下次运行
不复杂但容易忽略:日志路径要有写权限,目录存在且磁盘未满;脚本开头加一句 mkdir -p "$(dirname "$LOGFILE")" 很稳妥。










