我有一个BASH脚本,它运行各种sysadmin函数和系统检查。如果检查失败,则将变量设置为1
。只有几种类型的错误可能发生,所以我有一些变量用于描述错误,例如$login_error
和$timeout
。
在脚本结束时,如果遇到错误,会向我的团队发送一封电子邮件。在电子邮件中,我提供了一条简短的错误消息,描述了错误。我得到的问题是错误消息包含\n
字符,但我的嵌入式电子邮件不保留换行符。
我会告诉你我的意思。这是检查故障并通过电子邮件发送给我的功能:
checkFailure () {
if [[ $error_encountered -eq 1 ]]; then
[[ $timeout -eq 1 ]] && msg="Error 1: The device timed out\n"
[[ $login_error -eq 1 ]] && msg="${msg}Error 2: Failed to login to device\n"
[[ $sky_fall -eq 1 ]] && msg="${msg}Error 3: The sky is falling\n"
{ /usr/bin/nc <ip_of_my_sendmail_box> << EOF
mail from: server@domain.com
rcpt to: me@domain.com
data
to: me@domain.com
subject: Error during systems check
Content-Type: text/plain
$(printf "%b" "$msg")
Sent on: $(date)
.
quit
EOF
} 1>/dev/null
}
现在,除了$msg
中的换行符似乎从我的电子邮件中删除之外,此处的所有内容都按预期工作。如果我没有通过电子邮件发送这个文本,那么printf会很高兴地解释这些换行符并向我展示两行文字。
假设发生错误1和错误2,我会在电子邮件中说明这一点:
Error 1: The device timed outError 2: Failed to login to device
为什么没有换行?
如果我将$msg
文本更改为最后有两个\n\n
个字符,请执行以下操作:
[[ $timeout -eq 1 ]] && msg="Error 1: The device timed out\n\n"
[[ $login_error -eq 1 ]] && msg="${msg}Error 2: Failed to login to device\n\n"
然后我在电子邮件中得到了这个:
Error 1: The device timed out
Error 2: Failed to login to device
请注意它们之间的额外新行。
有没有人知道为什么我要么没有新行或两个换行符,而是从来没有想要的换行符。
答案 0 :(得分:3)
msg=""
[[ $timeout -eq 1 ]] && msg+=$'Error 1: The device timed out\n'
[[ $login_error -eq 1 ]] && msg+=$'Error 2: Failed to login to device\n'
[[ $sky_fall -eq 1 ]] && msg+=$'Error 3: The sky is falling\n'
答案 1 :(得分:1)
你的子shell正在吐出换行符,但是heredoc扩展正在丢弃它,因为它没有引用。
在你的shell中尝试printf %b $msg
来查看这个想法。
你需要使用类似printf %s\\n "$(printf %b "$msg")"
的东西来获得你想要的东西。
答案 2 :(得分:0)
感谢Glenn和Etan的回复!但是,我想我发现了这个问题。
事实证明问题更多的是Outlook(我用来阅读电子邮件)。它正在剥离那些特定线路的换行符。我不知道为什么。
this post describes the issue我看到了。
根据该帖子的建议,我的修正是将/t
字符添加到每个$msg
行的末尾。这导致Outlook没有剥离换行符。
我不知道为什么我的heredoc的其他部分没有被Outlook剥离它们的换行符。例如,我还cat
将一个日志文件放入充满新行的heredoc中,并显示正常。哦,好吧......
编辑:This post也有关于Outlook的此行为的良好信息。