Linux Shell脚本日志规范要求统一ISO8601时间戳与INFO/WARN/ERROR/DEBUG级别,封装log_info/log_error等函数,区分stdout与日志文件输出,记录入口参数、关键操作及错误上下文,并支持DEBUG开关与轻量轮转。

Linux Shell 脚本的日志规范输出,核心是让日志可读、可定位、可过滤、可归档——不是简单 echo 一堆文字,而是建立轻量但一致的记录习惯。
统一时间戳与日志级别
每条日志开头带 ISO8601 格式时间 + 明确级别(INFO/WARN/ERROR/DEBUG),方便排序和 grep 过滤:
- 用 date -Iseconds 或 date '+%Y-%m-%d %H:%M:%S' 生成时间前缀
- 定义函数封装日志输出,避免重复写法:
log_info() { echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] $*" | tee -a "$LOG_FILE"; }
log_error() { echo "$(date '+%Y-%m-%d %H:%M:%S') [ERROR] $*" | tee -a "$LOG_FILE" >&2; } - ERROR 级别默认重定向到 stderr,并仍写入日志文件,确保管道或重定向场景不丢错误
区分标准输出与日志文件
脚本运行时的“结果”(如成功生成的路径、返回值)走 stdout;过程记录、诊断信息、异常上下文走日志文件:
- 不要把 log_info 写进 stdout 流,否则影响下游命令解析(比如用脚本结果做 if 判断)
- 日志文件路径建议由变量控制(如 LOG_FILE="${LOG_DIR:-/var/log}/mytask.log"),支持外部覆盖,便于测试和部署隔离
- 启动时自动创建日志目录:mkdir -p "$(dirname "$LOG_FILE")"
关键操作必须留痕:入口、参数、退出状态
日志不是只记“出错了”,更要记清“谁、在什么条件下、做了什么”:
- 脚本开头记录执行命令行:log_info "Started with: $0 $*"
- 敏感参数(如密码、token)需脱敏再记录,或直接跳过:log_info "Running as user: $(whoami)"
- 每个重要命令后检查 $?,失败时连同命令本身、错误码、可能的 stderr 片段一并记录:
if ! cp "$SRC" "$DST"; then
log_error "cp failed (code $?) for '$SRC' → '$DST'";
exit 1;
fi
支持调试模式与日志轮转(轻量级)
生产环境不打 DEBUG 日志,但开发/排障时能一键开启;长期运行脚本需防日志撑爆磁盘:
- 用变量控制日志级别:if [[ "${DEBUG:-0}" == "1" ]]; then log_debug "..."; fi
- 单次脚本无需复杂轮转,但可加简单限制:tail -n 1000 "$LOG_FILE" > "$LOG_FILE.tmp" && mv "$LOG_FILE.tmp" "$LOG_FILE"(放在脚本末尾或定时任务中)
- 更稳妥做法:用系统 syslog(logger 命令)或交由 logrotate 管理,Shell 脚本只负责按格式输出到指定文件










