# 获取当前时间戳get_timestamp() { local format="${1:-full}" case "${format}" in full) date '+%Y-%m-%d %H:%M:%S' ;; date) date '+%Y-%m-%d' ;; time) date '+%H:%M:%S' ;; iso) date '+%Y-%m-%dT%H:%M:%S%z' ;; unix) date '+%s' ;; compact) date '+%Y%m%d%H%M%S' ;; ms) date '+%Y-%m-%d %H:%M:%S.%3N' ;; esac}# 使用示例log_with_timestamp() { local timestamp timestamp=$(get_timestamp "full") echo "${timestamp} $*"}
# 简单进度条show_progress() { local current="${1}" local total="${2}" local width=50 local percent=$(( current * 100 / total )) local filled=$(( current * width / total )) local empty=$(( width - filled )) printf "\r[" printf "%${filled}s" | tr ' ' '█' printf "%${empty}s" | tr ' ' '░' printf "] %3d%%" "${percent}"}# 使用示例for i in $(seq 1 100); do show_progress "${i}" 100 sleep 0.05doneecho ""
第5节:日志文件 Rotation
自动日志 rotation
#!/usr/bin/env bash# ============================================================# 日志 Rotation 框架# ============================================================# 配置LOG_DIR="/var/log/myscript"LOG_FILE="${LOG_DIR}/app.log"MAX_SIZE="10M" # 最大文件大小MAX_FILES=5 # 保留的旧日志文件数量COMPRESS=true # 是否压缩旧日志# 确保日志目录存在init_logging() { mkdir -p "${LOG_DIR}" touch "${LOG_FILE}"}# 检查并执行 rotationrotate_log() { local file="${1}" local max_size="${2}" local max_files="${3}" # 检查文件大小 if [ ! -f "${file}" ]; then return 0 fi local file_size file_size=$(stat -f%z "${file}" 2>/dev/null || stat -c%s "${file}" 2>/dev/null || echo 0) # 将大小转换为字节 local size_bytes size_bytes=$(human_to_bytes "${max_size}") if [ "${file_size}" -lt "${size_bytes}" ]; then return 0 fi # 执行 rotation for i in $(seq $(( max_files - 1 )) -1 1); do local prev=$((i - 1)) if [ -f "${file}.${prev}.gz" ]; then mv "${file}.${prev}.gz" "${file}.${i}.gz" elif [ -f "${file}.${prev}" ]; then mv "${file}.${prev}" "${file}.${i}" fi done # 当前文件变成 .1 mv "${file}" "${file}.1" # 压缩旧文件 if [ "${COMPRESS}" = true ]; then gzip "${file}.1" 2>/dev/null || true fi # 创建新文件 touch "${file}"}# 人类可读大小转字节human_to_bytes() { local size="${1}" local number="${size%[KMGkmg]}" local unit="${size: -1}" case "${unit}" in K|k) echo $(( number * 1024 )) ;; M|m) echo $(( number * 1024 * 1024 )) ;; G|g) echo $(( number * 1024 * 1024 * 1024 )) ;; *) echo "${number}" ;; esac}