I have a BASH script that runs various sysadmin functions and system checks. If a check fails, a variable is set to 1
. There are only a couple types of errors that can happen, so I have variables named to describe the error such as $login_error
and $timeout
.
At the end of the script, if an error was encountered, an e-mail is sent to my team. In the e-mail, I include a brief error message describing what the error was. The problem I'm getting is that the error messages contain a \\n
character, but my embedded e-mail doesn't preserve the newlines.
I'll show you what I mean. Here's the function that checks for failures and e-mails me:
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
}
Now, every thing here works as intended except that the newlines in $msg
get seemingly stripped from my e-mail. If I wasn't e-mailing this text, then printf will happily interpret the newlines and show me two lines with text.
Let's say that an error 1 and an error 2 happened, I'll get this in my e-mail:
Error 1: The device timed outError 2: Failed to login to device
Why no new line?
If I change the $msg
texts to have two \\n\\n
characters at the end, like so:
[[ $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"
then I get this in the e-mail:
Error 1: The device timed out
Error 2: Failed to login to device
Notice the extra new line between them now.
Does anyone know why I either get no newline or two newlines, but never the desired one newline.
Try ANSI-C quoting :
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'
Your sub-shell is spitting out the newline but the heredoc expansion is dropping it as it is unquoted.
Try printf %b $msg
in your shell to see the idea.
You need to use something like printf %s\\\\n "$(printf %b "$msg")"
to get what you want.
Thanks for the replies Glenn and Etan! However, I think I found the issue.
Turns out that the problem was more with Outlook (which I use to read the e-mails). It was stripping the line-breaks for those particular lines. I don't know why though.
this post describes the issue I was seeing.
My fix, as recommended by that post, was to add /t
character to the end of each $msg
line. This tricked Outlook into not stripping the line-breaks.
I have no idea why other parts of my heredoc don't get their line-breaks stripped by Outlook. For example, I also cat
a log file into the heredoc that's full of new lines, and that shows up fine. Oh well...
Edit: This post also has good info on this behavior by Outlook.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.