Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shell scripting, store command output in variable and preserve formatting [duplicate]

Tags:

bash

shell

unix

Possible Duplicate:
Capturing multiple line output to a bash variable

I have what is probably a basic scripting question, but I haven't been able to find an answer anywhere that I've looked.

I have an awk script that processes a file, and spits out a list of disabled systems. When I call it manually from the command line, I get formatted output back:

$awk -f awkscript datafile

The following notifications are currently disabled:

host: bar
host: foo

I am writing a wrapper script to call from my crontab, which will run the awk script, determine if there is any output, and email me if there is. It looks like (simplified):

BODY=`awk -f awkscript datafile`
if [ -n "$BODY" ]
then
echo $BODY | mailx -s "Disabled notifications" [email protected]
else
echo "Nothing is disabled"
fi

When run this way, and confirmed by adding an echo $BODY into the script, the output is stripped of the formatting (newlines are mainly what I'm concerned with), so I get output that looks like:

The following notitifications are currently disabled: host: bar host: foo

I'm trying to figure out how to preserve the formatting that is present if I run the command manually.

Things I've tried so far:

echo -e `cat datafile | awkscript` > /tmp/tmpfile
echo -e /tmp/tmpfile

I tried this because on my system (Solaris 5.10), using echo without the -e ignores standard escape sequences like \n . Didn't work. I checked the tmpfile, and it doesn't have any formatting in it, so the problem is happening when storing the output, not when printing it out.

BODY="$(awk -f awkscript datafile)"
echo -e "$BODY"

I tried this because everything I could find, including some other questions here on stackoverflow said that the problem was that the shell would replace whitespace codes with spaces if it wasn't quoted. Didn't work.

I've tried using printf instead of echo, using $(command) instead of `command`, and using a tempfile instead of a variable to store the output, but nothing seems to retain the formatting.

What am I missing, or is there another way to do this which avoids this problem all together?

like image 569
Madasi Avatar asked Jan 12 '12 14:01

Madasi


2 Answers

BODY=`awk -f awkscript datafile`
if [ -n "$BODY" ]
then echo "$BODY" | mailx -s "Disabled notifications" [email protected]
else echo "Nothing is disabled"
fi

Note the double quotes in the echo.

You can simplify this version, too:

echo -e `cat datafile | awkscript` > /tmp/tmpfile
echo -e /tmp/tmpfile

to just:

tmpfile=/tmp/tmpfile.$$
awkscript > $tmpfile
if [ -s $tmpfile ]
then mailx -s "Disabled notifications" [email protected] < $tmpfile
else echo "Nothing is disabled"
fi

Backquotes are useful (but better written as $(cmd args)) but do not have to be used everywhere.

like image 183
Jonathan Leffler Avatar answered Nov 14 '22 22:11

Jonathan Leffler


Using quotes should work, and does for me:

$ cat test.sh
#!/bin/bash -e

BODY=`cat test.in`
if [ -n "$BODY" ]; then
        echo "$BODY" | mailx -s "test" username
else 
        echo "Nothing"
fi

$ cat test.in

The following notifications are currently disabled:

host: bar
host: foo

$ ./test.sh
$

And this sends me a properly formatted email.

like image 36
Kevin Avatar answered Nov 14 '22 21:11

Kevin