示例说明
echo 散落各处的脚本无法运维:信息混在 stdout、错误没有级别、管道重定向时日志跟着数据流走丢。logger 函数收拢三点:级别作为第一个参数,debug 级受环境变量开关控制;error 与 warn 定向 stderr——stdout 留给真实数据,2>/dev/null 或 2>&1 的重定向选择权交给调用方;时间戳前缀让输出自带时间线。
技术要点
- 级别参数化并支持过滤
- 错误与警告定向 stderr
- 时间戳统一格式前缀
代码解读
log 的 case 分支决定目标流,printf 的三段式输出时间戳、大写级别、消息;log_debug 用算术短路实现可关断——VERBOSE 为零时 or true 兜住返回值防 -e 误杀。main 演示四级的典型用法:目录缺失是 error 并返回失败,空间不足是 warn 但继续。
使用建议
颜色输出要检测 tput 或终端存在性,管道下自动关闭。更复杂需求直接用 logger 命令接入 syslog。脚本输出与数据输出的分离是管道化复用的前提。
代码示例
#!/usr/bin/env bash
set -euo pipefail
readonly LOG_LEVEL="${LOG_LEVEL:-info}"
declare -i VERBOSE=0
[[ "${LOG_LEVEL}" == "debug" ]] && VERBOSE=1
_timestamp() { date +'%Y-%m-%dT%H:%M:%S'; }
log() {
local level="$1"
shift
local target=stdout
case "${level}" in
error) target=stderr ;;
warn) target=stderr ;;
esac
local prefix="[ ${level^^} ]"
printf '%s %s %s\n' "$(_timestamp)" "${prefix}" "$*" >&"${target}"
}
log_debug() { (( VERBOSE )) && log debug "$@" || true; }
log_info() { log info "$@"; }
log_warn() { log warn "$@"; }
log_error() { log error "$@"; }
main() {
log_info "开始同步目录 ${SYNC_DIR:-./data}"
log_debug "参数列表: ${*}"
if [[ ! -d "${SYNC_DIR:-./data}" ]]; then
log_error "同步目录不存在,中止"
return 1
fi
log_warn "磁盘剩余空间低于阈值,继续执行"
log_info "同步完成"
}
log_debug "脚本启动于 PID $$"
main "$@"