在 macos shell 脚本中记录带时间戳日志的核心是嵌入 date 命令并重定向或封装函数;推荐格式为 echo "$(date '+%y-%m-%d %h:%m:%s') [info] 消息",可封装 log() 函数统一管理,或用 exec + awk 全局自动添加时间戳,生产环境需结合日志轮转与权限控制。
在 macos 的 shell 脚本中记录带时间戳的运行日志,核心是把 date 命令嵌入日志输出,并配合重定向或函数封装,让每条日志自动附带精确、可读、一致的时间标记。
用 date + echo 直接输出带时间戳的日志
这是最轻量、最常用的方式,适合简单脚本或单次调试。关键是使用 date 的格式化参数,确保时区和精度符合本地习惯(macOS 默认使用系统时区)。
-
基础格式(推荐):
echo "$(date '+%Y-%m-%d %H:%M:%S') [INFO] 开始备份" -
含毫秒(需额外处理): macOS 的
date不原生支持%N(纳秒),但可用%3N获取毫秒(部分版本支持),更可靠的做法是:echo "$(date '+%Y-%m-%d %H:%M:%S').$(printf "%03d" $(($(date +%s%N)/1000000%1000))) [DEBUG] 连接数据库" -
写入文件: 用
>>追加到日志文件,例如:echo "$(date '+%Y-%m-%d %H:%M:%S') [RUN] Script started" >> /var/log/myapp.log
封装成通用日志函数
避免重复写 date 表达式,提高可维护性。函数可统一控制格式、级别、输出目标。
- 定义函数(放在脚本开头):
log() {<br> local level=${1:-INFO}<br> local msg=${2:-""}<br> echo "$(date '+%Y-%m-%d %H:%M:%S') [$level] $msg"<br>} - 调用示例:
log INFO "初始化配置"<br>log WARN "磁盘空间低于10%"<br>log ERROR "数据库连接失败"
- 搭配重定向使用:
log INFO "开始同步" >> /tmp/sync.log
自动添加时间戳到整个脚本的标准输出
如果想让脚本所有 echo 或命令输出都自动带时间戳(无需逐行改写),可用 stdbuf + awk 实现流式处理(macOS 自带 awk):
- 在脚本顶部加入:
exec > >(awk '{print strftime("%Y-%m-%d %H:%M:%S"), $0}' | tee -a /var/log/myscript.log) 2>&1 - 这样后续所有
echo、命令结果都会自动前置时间戳并写入日志文件 - 注意:该方式会捕获所有 stdout/stderr,适合调试或监控类脚本,不适用于需要交互的场景
结合日志轮转与权限管理(生产环境建议)
长期运行的脚本需防止日志无限增长,macOS 提供了 newsyslog 工具,也可手动控制:
- 限制日志大小后自动归档:
LOG_FILE="/var/log/myapp.log"<br>MAX_SIZE=10485760 # 10MB<br>if [ -f "$LOG_FILE" ] && [ $(stat -f "%z" "$LOG_FILE" 2>/dev/null) -gt $MAX_SIZE ]; then<br> mv "$LOG_FILE" "${LOG_FILE}.$(date +%Y%m%d_%H%M%S)"<br>fi - 确保日志目录可写(尤其写入
/var/log/时需 sudo):sudo mkdir -p /var/log/myapp<br>sudo chown $(whoami):admin /var/log/myapp
- 推荐路径:普通用户脚本优先用
~/Library/Logs/,避免权限问题











