Ubuntu下Crontab同时触发的Bash脚本日志需按执行完成后整体输出
解决多脚本同时执行日志混乱的方案
核心思路是让每个脚本的输出先临时缓存,执行完成后再整体追加到主日志,同时加上脚本标识和时间戳,保证日志块的完整性和可读性。
方案一:修改脚本内部实现(推荐)
在每个需要记录日志的脚本开头添加以下代码,自动捕获所有输出,执行完成后统一写入主日志:
# 生成唯一临时日志文件,避免多脚本冲突 TEMP_LOG=$(mktemp -t script_exec_log.XXXXXX) # 重定向当前脚本的所有标准输出和错误输出到临时文件 exec > "$TEMP_LOG" 2>&1 # 捕获脚本退出信号(无论成功/失败),确保日志能被写入并清理临时文件 trap ' # 定义日志头部/尾部标识,方便区分不同脚本的执行记录 LOG_HEADER="===== 脚本: $(basename "$0") 执行开始时间: $(date '+%Y-%m-%d %H:%M:%S') =====" LOG_FOOTER="===== 脚本: $(basename "$0") 执行结束时间: $(date '+%Y-%m-%d %H:%M:%S') =====" # 将临时文件内容连同标识一起追加到主日志 { echo "$LOG_HEADER" cat "$TEMP_LOG" echo "$LOG_FOOTER" echo "" } >> ~/path/to/custom/log/file # 清理临时文件 rm -f "$TEMP_LOG" ' EXIT # 以下是你的脚本原有业务代码 # ...
方案二:在Crontab中配置(无需修改脚本)
如果不想改动脚本内容,可以直接在Crontab任务中添加捕获逻辑,每个任务的执行输出先存到临时文件,执行完成后再写入主日志:
假设你的Crontab原本是:
0 8 * * * /path/to/script1.sh 0 8 * * * /path/to/script2.sh
修改为:
0 8 * * * bash -c ' TEMP_LOG=$(mktemp -t cron_script_log.XXXXXX) /path/to/script1.sh > "$TEMP_LOG" 2>&1 { echo "===== 脚本: script1.sh 执行开始时间: $(date '+%Y-%m-%d %H:%M:%S') =====" cat "$TEMP_LOG" echo "===== 脚本: script1.sh 执行结束时间: $(date '+%Y-%m-%d %H:%M:%S') =====" echo "" } >> ~/path/to/custom/log/file rm -f "$TEMP_LOG" ' 0 8 * * * bash -c ' TEMP_LOG=$(mktemp -t cron_script_log.XXXXXX) /path/to/script2.sh > "$TEMP_LOG" 2>&1 { echo "===== 脚本: script2.sh 执行开始时间: $(date '+%Y-%m-%d %H:%M:%S') =====" cat "$TEMP_LOG" echo "===== 脚本: script2.sh 执行结束时间: $(date '+%Y-%m-%d %H:%M:%S') =====" echo "" } >> ~/path/to/custom/log/file rm -f "$TEMP_LOG" '
关键说明
mktemp生成的临时文件具有唯一性,不会被其他脚本覆盖,默认存放在/tmp目录,无需额外权限。trap命令确保脚本无论正常结束还是异常退出,都会执行日志写入和临时文件清理。- 日志头部/尾部的标识可以帮助你快速定位每个脚本的执行时间段和内容范围,提升可读性。
- 主日志文件需确保Crontab执行用户有写入权限,建议使用用户家目录下的路径(如
~/scripts/logs/exec_all.log)。
内容的提问来源于stack exchange,提问作者Shreyan Das
相关产品推荐
相关产品推荐

