Send email via echo command with data from variable - bash

once a day a CSV is generated that includes a single column with several rows with names (one row for each name)
I want to send these names as an email to a certain distribution list.
This is what I have so far:
#!/bin/bash
names=`cat /list_of_names.csv`
echo "$names" | mail -s "You got mail" "email#email.com"
The problem is that the email is always empty. It is correctly delivered with the right subject line, but there is no text in it.
When I check the variable manually in the console (echo "$names") all names are listed correctly.
Why is the email empty? Does anyone have an idea?

Just in case you have problems reading the file
cat /list_of_names.csv 2>&1 | mail -s "You got mail" "email#email.com"

Related

Unix Shell Script does not send intended email

I have a shell script like this. The purpose of this script is to tail+head out a certain amount of data from file.csv and then send it to email Bob#123.com. DataFunction seems to work fine alone however when I try to call DataFunction within the email function body. It seems it sends a empty email with the correct Title and destination. The body of the email is missing which should be the data from DataFunction. Is there a workaround for this ? Thank you in advance.
#!/bin/bash
DataFunction()
{
tail -10 /folder/"file.csv" | head -19
}
fnEmailFunction()
{
echo ${DataFunction}| mail -s Title Bob#123.com
}
fnEmailFunction
You are echoing an unset variable, $DataFunction (written ${DataFunction}), not invoking the function.
You should use:
DataFunction | mail -s Title Bob#123.com
You may have been trying to use:
echo $(DataFunction) | mail -s Title Bob#123.com
but that is misguided for several reasons. The primary problem is that it converts the 10 lines of output from the DataFunction function into a single line of input to mail. If you enclosed the $(DataFunction) in double quotes, that would preserve the 'shape' of the input, but it wastes time and energy compared to running the command (function) directly as shown.
Try this:
mail -s "Title" "bob#123com" <<EOF
${DataFunction}
EOF
I tried #0xAX's answer and couldnt get it to work properly within a bash script. You simply need to save the output of DataFunction() in some variable. You can simply use these three lines to achieve this.
#!/bin/bash
VAR1=`tail -10 "/folder/file.csv" | head -19`
echo $VAR1 | mail -s Title Bob#123.com

How to avoid sending e-mails that result in "Extra line breaks in this message were removed."

I have a bash script that send an email like so ...
/bin/mailx -s "Unsatisfied dependencies report for the [$lc] YUM repo" red#example.com < /tmp/$prog.output
... when the email arrives to Outlook I get that stupid message about "Extra line breaks in this message were removed". I tried running unix2dos on the /tmp/$prog.output file but that results in the report being sent as binary attachment.
Is there anything I can do from my bash script to prevent the annoying "extra line break in this message were removed" message?
From the outlook documentation
"By default, the Auto Remove Line Breaks feature in Outlook is enabled. This causes the line breaks to be removed. Any two or more successive line breaks are not removed."
So maybe doubling up your new lines would avoid that.
In my situation I was able to use awk
echo "$variable" | awk '{ print $0" " }' | mail -s ....
This reads every single line, and re-prints it with three spaces at the end. Outlook is now happy.
https://blog.dhampir.no/content/outlook-removes-extra-line-breaks-from-plain-text-emails-how-to-stop-it

Extra ! sign in email message body while sending mail through shell script

I am sending emails through shell script, in which I get message body from a text file. Issue comes when my disclaimer goes long, it starts getting extra ! sign in between.
Please suggest me to remove that without shortening or giving extra lines between the disclaimer. Let me know if you need any details.
Needed(say):
I am sending emails through shell script, in which I get message body from a text file. Issue comes when my disclaimer goes long, it starts getting extra ! sign in between.
Please suggest me to remove that without shortening or giving extra lines between the disclaimer. Let me know if you need any details.
Output in mail:
I am sending emails through shell script, in which I get message body from a text file. Issue comes when my disclaimer goes long, it starts getting extra ! sign in between.
Please suggest me to remove that without shortening or giving e!xtra lines between the disclaimer. Let me know if you need any details.
Here you can see that we are getting ! sign in extra word. Just keep the body long (sry I couldn't provide you the actual text), and you will get the ! sign.
Code I am using - to read from text file
EMAILMSG=$(cat $2) # $2 is path of text file
to send email
(echo -e $EMAILMSG;) | mailx -s "$SUBJECT" -b "abc#abc.com" $EMAIL -r $MAILBCC
I think this will help you to understand the situation. Please let me know anyone need further details.
I found this: Random exclamation mark in email body using CDO
It seems to indicate long lines are the problem. Try this using fold to wrap lines:
fold -s "$2" | mailx -s "$SUBJECT" -b "abc#abc.com" "$EMAIL" -r "$MAILBCC"
Style recommendations:
don't use $ALL_CAPS_VARS (here's why not)
always quote your "$vars" except when you know exactly when not to.

UNIX Beginner: grep save to a file doesn't work

Am a beginner in unix and I have just landed into a snag. The bash app I am working on is very simple and is one that can add contacts, and remove contacts (based on first and last name). Below is a part of my code, and for some reason, the grep displays the remaining contacts fine when excluding the (>contacts_file), but doesn't save to the file when including (>contacts_file). It instead leaves the 'contacts_file' blank. How can I fix this? Or is there a better way to search contacts in a contact's file? format in contacts_file is: firstname lastname
echo "[Remove a contact]"
echo "First Name: "
read first0
echo "Last Name: "
read last0
grep -vw -e "$first0 $last0" contacts_file >contacts_file
You cannot direct output to the same file in which you are grepping.
The reason is that the shell opens that output file for writing and hence makes it empty.
The solution is to direct output to a temp file and then move the temp file to contacts_file if you want to replace it.

reading multiple items semi-interactively from the user in bash

I'm trying to read multiple items from the user in a shell script, with no luck. The intention is to read a list of files first (which are read from the stdin pipe), and then read twice more to get two strings interactively. What I'm trying to do is read a list of files to attach in an email, then the subject and finally the email body.
So far I have this:
photos=($(< /dev/stdin))
echo "Enter message subject"
subject=$(< /dev/stdin)
echo "Enter message body"
body=$(< /dev/stdin)
(plus error checking code that I omit for succintness)
However, this gets an empty subject and body presumably because the second and third redirections get EOF.
I've been trying to close and reopen stdin with <&- and stuff but it doesn't seem to work that way.
I even tried using a separator for the list of files, using a "while; read line" loop and break out of the loop when the separator was detected. But that didn't work either (??).
Any ideas how to build something like this?
So what I ended up doing is based on ezpz's answer and this doc: http://www.faqs.org/docs/abs/HTML/io-redirection.html Basically I prompt for the fields first from /dev/tty, and then read stdin, using the dup-and-close trick:
# close stdin after dup'ing it to FD 6
exec 6<&0
# open /dev/tty as stdin
exec 0</dev/tty
# now read the fields
echo "Enter message subject"
read subject
echo "Enter message body"
read body
# done reading interactively; now read from the pipe
exec 0<&6 6<&-
photos=($(< /dev/stdin))
Thanks!
You should be able to use read to prompt for the subject and body:
photos=($(< /dev/stdin))
read -rp "Enter message subject" subject
read -rp "Enter message body" body
Since it is possible that you have a varying number of photos, why not just prompt for the known fields first and then read 'everything else'. It is much easier than trying to get the last two fields of an unknown length in an interactive manner.
# Prompt and read two things from the terminal (not from stdin), then read stdin.
# The last line uses arrays, so is BASH-specific. The read lines are portable.
# - Ian! D. Allen - idallen#idallen.ca - www.idallen.com
read -p "Enter message subject: " subject </dev/tty
read -p "Enter message body: " body </dev/tty
photos=($(</dev/stdin))

Resources