You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Bash脚本输出重定向至日志,仅把错误传给邮件脚本?

问题解决与代码修正

核心问题分析

  1. 重定向逻辑错误:原代码中&>> "$OUT_FILE" 2> ERROR_OUTPUT无法同时将所有输出写入日志并单独捕获错误——&>>已经将stdout和stderr合并写入日志,后续的2>不会生效。
  2. 错误内容传递方式错误:直接使用$ERROR_OUTPUT传递的是变量名而非实际错误内容,且未加引号导致内容被shell拆分。
  3. mail命令参数错误:多数环境下mail的主题参数是-s而非-a,-a通常用于添加附件或自定义头信息。
  4. eval存在安全风险:拼接命令字符串再eval执行,若变量包含特殊字符会引发意外执行。

修正后的run_job.sh

# 定义临时错误文件,用进程ID避免冲突
ERROR_FILE="/tmp/job_error_$$.log"

{
  printf "\n----- PROCESS STARTED %s -----\n" "$(date +%Y-%m-%d\ %H:%M:%S)"

  # 替换eval为直接执行,避免安全风险
  printf "Executing command: cd %s && %s\n\n" "$JOB_FOLDER_PATH" "$EXEC_COMMAND"
  cd "$JOB_FOLDER_PATH" && "$EXEC_COMMAND"
  COMMAND_EXIT_CODE=$?

  printf "\n----- PROCESS ENDED %s -----\n\n" "$(date +%Y-%m-%d\ %H:%M:%S)"
} > >(tee -a "$OUT_FILE") 2> >(tee -a "$OUT_FILE" > "$ERROR_FILE")

# 命令失败时发送邮件
if [ "$COMMAND_EXIT_CODE" -ne 0 ]; then
    # 读取错误文件内容作为邮件正文,双引号保留格式
    bash ./send_email.sh "Job Failed" "$(cat "$ERROR_FILE")"
fi

# 清理临时文件
rm -f "$ERROR_FILE"

修正后的send_email.sh

MAIL_SUBJECT="$1"
MAIL_BODY="$2"

# 修正mail命令参数:-s指定主题,-a添加From头
echo "$MAIL_BODY" | \
mail -s "$MAIL_SUBJECT" \
     -a "From: Kaizen Service <service@kaizen.co.uk>" \
     "$(grep -o '^[^#]*' "$MAILING_LIST_FILE" | tr '\n' ',')"

关键改进说明

  • 重定向逻辑:通过tee实现双输出——stdout和stderr都写入日志文件,同时stderr单独写入临时错误文件。
  • 安全执行命令:去掉eval,直接执行cd "$JOB_FOLDER_PATH" && "$EXEC_COMMAND",避免变量特殊字符引发的安全问题。
  • 正确传递内容:用$(cat "$ERROR_FILE")读取错误内容,并用双引号包裹,保证内容格式和完整性。
  • 兼容mail命令:改用-s指定主题,符合多数mail/mailx工具的参数规范。

内容的提问来源于stack exchange,提问作者Tamir Hen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 06:37:06