Bash-script: running command and pipeing it to mail gives mail without line breakse

Posted on 2014-04-26
Last Modified: 2014-04-27
I have a bash script that needs to do this:

1) Run a external command and store the output either in variable or tempfile.
2) Add the output as a body in a mail with the mail-command.

The mail body needs to contain static text both before and after the output from the external command which excludes the solution to pipe it directly by

external-command | mail

I have tried this:
1) Storing output of external-command in a variable by running
and creating another variable that contains static text+variable+static text and run
echo($anothervariable) | mail
2) pipeing the external-command output to a tempfile and do
(cat pretext; cat tempfile; cat posttext) | mail ...

Both my solutions above gives me a mail without line breaks with makes it unusable.

Please advice how to send my text with proper line breaks.

Best regards
Question by:Kvistofta
  • 4
  • 3
  • 2
  • +1
LVL 19

Expert Comment

ID: 40025026
Whenever you reference the variable, enclose it in double quotes, otherwise the shell will swallow any internal end-of-line markers.  e.g.

    echo "$anothervariable" | mail
LVL 24

Expert Comment

ID: 40025030
Revisit the nature of the breaks with regard to production of newline, carriage returns, even for checking the hex or decimal value of character. For variables you can try to wrap them with double quotes.
LVL 19

Expert Comment

ID: 40025034
Another option would be

   ( cat pretext ; external-command; cat posttext) | mail

If you do have the data in a file, you can use a single "cat" command

    cat pretext tempfile posttext | mail

(a command actually using "cat" for its intended purpose - to concatenate two or more files!)
LVL 61

Expert Comment

ID: 40025182
It is much simpler... No variables no tempfiles
(echo C1 START ; command1 && echo C1 FINISH || echo C1 FAIL ; .... C2) | mail -s "REPORT `date`" you@work
LVL 17

Author Comment

ID: 40025391
Putting the variable between ":s does not help. This is how my script looks like right now:

                commandoutput=`ls -l /usr`
                echo Output from external command:
                echo -----------
                echo "$commandoutput"
                echo -----------
                echo Length of result: $outputlength
                if [ "$outputlength" -gt "20" ] ; then
                        echo "$(date +%H:%M:%S) : Result is $outputlength bytes, sending mail to $email!" >> $LOGFILE
                        SUBJECT="Email notification from CHANGE regarding zone $domain"

                        (echo "Line1\r\n"; \
                         echo "Line2\r\n"; \
                         echo "$commandoutput\r\n"; \
                         echo "Line3\r\n"; \
                         echo "Line4\r\n";) \
                         | mail \
                                                -a "From: $EMAILFROM" \
                                                -a "MIME-Version: 1.0" \
                                                -a "Content-Type: text/html" \
                                                -s "$SUBJECT" \

Open in new window

The output on the screen looks good:

Output from external command:
total 100
drwxr-xr-x   2 root root 40960 Apr 24 12:04 bin
drwxr-xr-x   2 root root  4096 Apr 24 09:11 games
drwxr-xr-x  32 root root 16384 Apr 24 12:04 include
drwxr-xr-x  67 root root 12288 Apr 24 12:04 lib
drwxr-xr-x  10 root root  4096 Mar  3 13:33 local
drwxr-xr-x   2 root root 12288 Apr 24 12:04 sbin
drwxr-xr-x 124 root root  4096 Apr 24 12:04 share
drwxr-xr-x   4 root root  4096 Apr 24 12:04 src
Length of result: 404

Open in new window

However, the email looks weird. Here is a screen dump from the receivers gmail:

Screendump from gmail
Not even my \r\n makes proper line breaks....?
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

LVL 61

Expert Comment

ID: 40025466
You dont need to use \r \n because ECHO will add proper line nedings without it.
LVL 19

Expert Comment

ID: 40025587
One problem with your code is that echo needs the "-e" option for it to interpret backslash sequences - as you can see from your screen capture, your "\r\n" in the echo has been sent as 4 separate characters (backslash, r, backslash and n).  so
    echo -e "${LINE1}\r\n"
would do what you are trying to do.

"echo" will add a \n to the end of the line (unless you use the "-n" flag on it), so you don't need to put that in, just the \r:
    echo -e "${LINE1}\r"

Another problem is the line echoing "$commandoutput" - you add a carriage-return and linefeed at the end of the variable, but that does nothing to change the linefeeds within the variable (i.e. between the lines that make up the "ls" output).

If you want to have \r\n line endings on your mail, a better solution would be the unix2dos command (in the "dos2unix" package on Ubuntu, or the "unix2dos" on RedHat).  Just use normal UNIX line endings on your echo commands, then pipe the result through unix2dos before passing to the mail program:
(echo "Line1"; \
                         echo "Line2"; \
                         echo "$commandoutput"; \
                         echo "Line3"; \
                         echo "Line4";) \
                         | unix2dos | mail \
                                                -a "From: $EMAILFROM" \

Open in new window

That said, none of the above is required here!
LVL 19

Accepted Solution

simon3270 earned 500 total points
ID: 40025589
Your problem is the

    -a "Content-Type: text/html"

This tells the receiving email client that your email is in HTML (ugh!), but it isn't!

To fix, either make it HTML (easiest would be to add a <pre> tag at the start, and </pre> at the end), or change that header item to say it's plain text.

    -a "Content-Type: text/plain"
LVL 61

Expert Comment

ID: 40025593
Internet standard is unix line breaks. echo adds them without escapes.

-a parameter is obsolete as text/plain is assumed if nothing is set...
LVL 17

Author Comment

ID: 40026610
Weeeh! I have tried all sorts of recommended solutions above when it comes to adding/changing line breaks but nothing happened. Until I got noticed that I used text/html in the header. Duh! Sorry folks! I have learned a lot from all of your comments and suggested solutions above.

Best regards

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

This article will explain how to establish a SSH connection to Ubuntu through the firewall and using a different port other then 22. I have set up a Ubuntu virtual machine in Virtualbox and I am running a Windows 7 workstation. From the Ubuntu vi…
Every server (virtual or physical) needs a console: and the console can be provided through hardware directly connected, software for remote connections, local connections, through a KVM, etc. This document explains the different types of consol…
Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
Learn how to find files with the shell using the find and locate commands. Use locate to find a needle in a haystack.: With locate, check if the file still exists.: Use find to get the actual location of the file.:

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now