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

Bash拼接换行字符串发邮件时最后一行未换行问题

问题根因

你写的message拼接逻辑本身没有问题,本地echo "$message"输出正常就是最好的证明。格式错乱完全是内容传给mail工具的环节出的问题,核心原因有两个:

  • 换行符不符合邮件传输标准
    按照邮件协议RFC 5322要求,邮件正文的行分隔符必须是CRLF格式(也就是\r\n,回车+换行组合),你脚本里拼接的是Unix系统原生的纯LF换行符(\n)。终端对纯LF换行兼容性很好,能正常识别为换行,但不少版本的mail发送组件、邮件客户端不认孤立的LF,会把它当成普通空白字符,直接导致相邻行被合并到同一行显示。
  • 变量传参没加双引号触发了shell的单词拆分
    如果你调用mail的时候没给$message加双引号——比如写了echo $message | mail xxx@xx.com,或者直接把$message当参数传给mail——shell会自动把变量里所有的换行、制表符、连续空格都当成分隔符,拆分后再传给命令,这些分隔符最终会被替换成单个空格。受mail自身输入解析逻辑的影响,不一定所有换行都会被替换成空格,经常就表现为最后几行被合并到一起。

顺便提一句你脚本里的逻辑bug:检测到无文件夹时你直接echo "No folders found",但这段内容没有赋值给message,真到无文件夹的场景,你发出去的邮件里根本看不到这段提示。

修复方法
  1. 先把空场景的提示内容赋值给message,不要直接echo打印
  2. 所有引用message变量的地方一律加双引号,避免shell自动拆分内容
  3. 拼接内容时直接用CRLF当换行符,避免mail组件识别错误
  4. 不要用命令替换的方式传递正文(命令替换会自动删掉内容末尾所有连续换行,很容易触发格式问题),直接用双引号包裹变量通过管道传给mail即可

修正后的参考脚本:

#!/bin/bash
message=""
CRLF=$'\r\n'

for f in /mnt/backup/*; do
    if [ -d "$f" ]; then
        message+="${f} is a folder${CRLF}"
    fi
done

if [ -z "$message" ]; then
    message="No folders found${CRLF}"
fi

# 发邮件示例,主题和收件人按实际情况替换
echo "$message" | mail -s "Backup directory scan result" admin@example.com

如果改完还是有格式问题,可以在管道里加个换行转换工具处理下:echo "$message" | unix2dos | mail -s "xxx" admin@example.com


内容的提问来源于stack exchange,提问作者Der Korrigierer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:15:37