Send an email to a email group using shell script - linux

Below is my shell script that is working fine.
#!/bin/bash
DATE_YEST_FORMAT2=`perl -e 'use POSIX qw(strftime); print strftime "%Y%m%d",localtime(time()- 3600*96);'`
echo $DATE_YEST_FORMAT2
QUERY1=`hive -e "
set mapred.job.queue.name=hdmi-technology;
SELECT SUM(total_items_purchased), SUM(total_items_missingormismatch) from lip_data_quality where dt='$DATE_YEST_FORMAT2';`
QUERY2=`hive -e "
set mapred.job.queue.name=hdmi-technology;
SELECT 100 * SUM(total_items_missingormismatch*1.0) / SUM(total_items_purchased) FROM lip_data_quality where dt='$DATE_YEST_FORMAT2';"`
echo "Total items purchased: `echo $QUERY1 | awk '{print $1}'`"
echo "Total Items MissingorMismatch: `echo $QUERY1 | awk '{print $2}'`"
echo "Error Percentage: $QUERY2"
I am running the above shell script like this below-
sh -x test.sh
Problem Statement:-
From the above shell script, I am getting below three things from the last three echo statements-
Total items purchased
Total Items MissingorMismatch
Error Percentage
I need to send all these above three things in an email to our email group we have DL-host#company.com by using that shell script above or suppose if I have 10 email list to which I need to send email with the same contents and subjects, then I think, I can store all these 10 emails list in some variable and just read it from there and keep on sending, right?. Is this possible to do it? I was thinking email structure like this below, just making very simple.
Subject
Test Data
Mail Body
Total items purchased:- Some Number
Total Items MissingorMismatch:- Some Number
Error Percentage:- Some Number
Any thoughts will be appreciated.
Update, After trying larsks suggestions, I am getting only last echo statement in an email meaning only the error percentage one, not all three in a single email:-
#!/bin/bash
DATE_YEST_FORMAT2=`perl -e 'use POSIX qw(strftime); print strftime "%Y%m%d",localtime(time()- 3600*96);'`
echo $DATE_YEST_FORMAT2
QUERY1=`hive -e "
set mapred.job.queue.name=hdmi-technology;
SELECT SUM(total_items_purchased), SUM(total_items_missingormismatch) from lip_data_quality where dt='$DATE_YEST_FORMAT2';`
QUERY2=`hive -e "
set mapred.job.queue.name=hdmi-technology;
SELECT 100 * SUM(total_items_missingormismatch*1.0) / SUM(total_items_purchased) FROM lip_data_quality where dt='$DATE_YEST_FORMAT2';"`
echo "Total items purchased: `echo $QUERY1 | awk '{print $1}'`"
echo "Total Items MissingorMismatch: `echo $QUERY1 | awk '{print $2}'`"
echo "Error Percentage: $QUERY2" | mail -s "Test Data" rj#host.com

You typically use the /bin/mail program to send email from a shell script. You provide a subject and recipients on the command line and the message body on stdin. For example, inside your script you could do something like this:
{
echo "Total items purchased: `echo $QUERY1 | awk '{print $1}'`"
echo "Total Items MissingorMismatch: `echo $QUERY1 | awk '{print $2}'`"
echo "Error Percentage: $QUERY2"
} | mail -s "Test Data" DL-host#company.com
You can also pipe the output of an existing script into mail (if you don't want to modify the script, or if you only want to send mail somtimes):
<your script> | mail -s "Test Data" DL-host#company.com
You can specify multiple recipients on the command line, so:
... | mail -s "Test Data" address1#company.com address2#company.com
and so forth.

Related

check server is bounced or not with time and date

(if server shows time like 08:14 - then print server is up but if server shows date like Nov13 - print server is not up and send an alert message)
#!/bin/ksh
var1="$(ps -ef | grep 'abc' | grep -v 'grep' | tr -s " " | cut -d ' ' -f5)"
var2="$(date "+%H:%M")"
date="$(date "+%b%d")"
if [ "$var1" == "$var2" ]; then
echo "Server has been bounced" > final.txt
echo " Success"
elif expr "$var1" ">" "$var2" >/dev/null; then
echo "Server has been bounced" > final.txt
echo " Success" > final.txt
elif [ "$var1" == "$date" ]; then
echo "Server is not bounced" > final.txt
echo " Failure" > final.txt
mail -s " Failure, Server is not bounced " final.abc#acb.com
fi
I tried to take the output of var1 with this following command of the server 5th column to check server is bounced or has been up or not
var1=echo "ps -ef | grep 'abc' | grep -v 'grep' | tr -s " " | cut -d ' ' -f5"
var1 output will be either date or time depends on if the server is bounced or not, if bounced shows time if not then shows date
var2=echo "date "+%H:%M" "
var2 output will be today's time.
Keeping in mind that time can be different also not on real time it is checking so if var1 output shows 03:14 and current time is 05:16 then also need to show server is up which i am trying with this
else if expr "$var1" ">" "$var2" >/dev/null
and then this command
date=echo "date "+%b%d" "
date output will be just a format like (Nov15) if the var1 output will be in the format of date variable then have to show server is not bounced and not up
but if var1 output will show time like 02:12 then have to compare with format of var2 and show server is bounced and up
stuck with the script in middle time script is working but date one is not giving the output
With the following you could get the amount of seconds since midnight:
$(($(date '+(%H*60+%M)*60+%S')))
Using -o etimes in ps you can get the amount of seconds since the process is running.
If you know the PID, you can do: ps -p <pid> -o etimes=. If you do not know the PID, you can use grep as you were already doing:
ps -e -o etimes,command|grep abc|awk '{print $1}'
Once you have both values, you can compare if the process running time is greater than amount of seconds since midnight.

How can I send a mail in linux shell script, using mail, but also awk?

What I really want is, I have a file: example.txt
The file is structured this way: FirstName LastName UserID Grade
I have two options: If the Grade is greater than 5 I want a mail to the user via [UserID]:
Dear [FirstName] [LastName]!
On this subject, your grade is [Grade]!
The second option is: If the [Grade] is less than 5 I want a mail to the user via [UserID]:
Dear [FirstName] [LastName]!
On this subject, your grade was less than 5!
Using awk'{print $1}' etc.
Thanks in advance!
Try the following script file :
#!/bin/bash
your_grade_files="/path_to_file.txt"
while read p; do
FirstName=$(echo $p | awk -F' ' '{print $1}')
LastName=$(echo $p | awk -F' ' '{print $2}')
UserID=$(echo $p | awk -F' ' '{print $3}')
Grade=$(echo $p | awk -F' ' '{print $4}')
if [ "$Grade" -gt 5 ]
then
mail -s "Enter your subject here" $UserID <<< "Dear $FirstName $LastName! On this subject, your grade is [ $Grade ] "
else
mail -s "Enter your subject here" $UserID <<< "Dear $FirstName $LastName! On this subject, your grade was less than 5!"
fi
done < $your_grade_files
Based on your question , You ll need to read the contents of the file iteratively
As you parse the contents line by line you can apply the mail to be triggered , based on the Grade value
while read line; do
grade = $(echo $line | awk -F' ' '{print $4}')
userid = $(echo $line | awk -F' ' '{print $3}')
if [[ $grade -gt 5]] then
sendMail $userid $grade
done < file.txt
func sendMail(){
userid = $1
grade = $2
MESSAGE="[$] : Your Grade -- $2"
SUBJECT="SOME SUBJECT"
TOADDR="u#u.com"
FROM="DONOTREPLY"
echo $MESSAGE | mail -s "$SUBJECT" $TOADDR -f $FROM
}
You can further modify the code snippet based on your requirement

Send message to group in Linux

I found the way to send message to currently logged in user by username:
who | grep username | cut -c1-20 | while read line; do printf "Message Text" | write $line ; done
However, is there anyway I can send message to currently logged in user by group?
Thanks for your help.
So... To send a message to every logged in user in a particular group, on every tty they're logged in to...
#!/bin/sh
usage() {
cat <<-EOT
Usage: writegroup groupname [message]
where [message] will be taken from stdin if not provided on the command line.
EOT
}
if [ $# -eq 0 ]; then
usage
exit 1
fi
groupname="$1"
shift
message="$*"
if [ -z "$message" ]; then
read message
fi
who | while read user tty junk; do
if groups "$user" | grep -wq "$groupname"; then
echo "$message" | write "$user" "$tty"
fi
done
Provided you set the variable group to the group you're interested in, you can try this:
for i in $(who -u | cut -d " " -f1 | sort | uniq); do if echo $(groups $i | cut -d " " -f3-) | grep $group >/dev/null; then echo "Message Text" | write $i; fi; done
$(who -u | cut -d " " -f1 | sort | uniq) gives the list of user logged in.
$(groups $i | cut -d " " -f3-) gives all groups a user belongs to.
The grep statement will reduce the list to the user belonging to the $group

shellscript - for loop - grep mail id according to user input from file

I am having user id's and equivalent mail ids in file. according to user input ( i.e, we will give input as "apple") it should grep only mail id (only apple#gmail.com) and stored in email=$(...)
in-between user ids & mail ids have one space gap in file
mail id's in file
user_id's mail_id's
apple apple#gmail.com
mango 123#ymail.com
cat cat#hotmail.com
etc...
sample
email=$(....)
msg= dont run jobs in login node
echo -e "$msg" |mail -s "RAM limit exceeded in iitmlogin4" "$email"
Your code can use awk:
# userid to search
userid="apple"
email=$(awk -v u="$userid" '$1 == u {print $1}' mail.file)
msg='dont run jobs in login node'
echo -e "$msg" | mail -s "RAM limit exceeded in iitmlogin4" "$email"
why not a function?
email(){
userid=$1
awk "/^$userid / { print \$2; }"
}
now to use it just do:
$ cat /tmp/foo
apple apple#gmail.com
mango 123#ymail.com
cat cat#hotmail.com
$ email apple < /tmp/foo
apple#gmail.com
from there it's all simple:
$ apple_mail=$(email apple < /tmp/foo )
$ echo $apple_mail
apple#gmail.com

new line in shell script

I have the below command in my shell script to send all the four echo statements in one email
{
echo "Data Successfully loaded into LIP table"
echo "Total Items Purchased: `echo $QUERY1 | awk '{print $1}'`"
echo "Total Items MissingorMismatch: `echo $QUERY1 | awk '{print $2}'`"
echo "Error Percentage: $QUERY2"
} | mailx -s "Report for $DATE_YEST_FORMAT1" -r rj#host.com user2#host.com
But when I see my email, I get the output like below which I don't want-
Data Successfully loaded into LIP table Total Items Purchased: 3956391
Total Items MissingorMismatch: 975825 Error Percentage: 24.66452380464924
I need output something like below as line by line.
Data Successfully loaded into LIP table
Total Items Purchased: 3956391
Total Items MissingorMismatch: 975825
Error Percentage: 24.66452380464924
Any suggestion why is it happening like this? I am running SunOS (Solaris).
Update:-
After trying the suggestion give by Kevin
QUERY1=`hive -e "
set mapred.job.queue.name=hdmi-technology;
SELECT SUM(total_items_purchased), SUM(total_items_missingormismatch) from lip_data_quality where dt='$DATE_YEST_FORMAT2';"`
QUERY2=`hive -e "
set mapred.job.queue.name=hdmi-technology;
SELECT 100 * SUM(total_items_missingormismatch*1.0) / SUM(total_items_purchased) FROM lip_data_quality where dt='$DATE_YEST_FORMAT2';"`
mailx -s "LIP Data Quality Report for $DATE_YEST_FORMAT1" -r rj#host.com rj#host.com uname#host.com <<EOF
Data Successfully loaded into LIP_DATA_QUALITY table
Total Items Purchased: $(echo $QUERY1 | awk '{print $1}')
Total Items MissingorMismatch: $(echo $QUERY1 | awk '{print $2}')
Error Percentage: $QUERY2
EOF
Output that I got in an email-
Data Successfully loaded into LIP_DATA_QUALITY table
Total Items Purchased: $(echo 3712928 393455 | awk '{print }')
Total Items MissingorMismatch: $(echo 3712928 393455 | awk '{print }')
Error Percentage: 10.596892802661404
Which is not right.. I should be getting output like this-
Data Successfully loaded into LIP_DATA_QUALITY table
Total Items Purchased: 3712928
Total Items MissingorMismatch: 393455
Error Percentage: 10.596892802661404
I am running SunOS
bash-3.00$ uname -a
SunOS lvsaishdc3in0001 5.10 Generic_142901-02 i86pc i386 i86pc
It's possible that mailx ignores single newlines and separates paragraphs by an empty line, similar to tex and our own SO.
That combined with a heredoc
mailx -s "Report for $DATE_YEST_FORMAT1" -r rj#host.com user2#host.com <<EOF
Data Successfully loaded into LIP table
Total Items Purchased: `echo $QUERY1 | awk '{print $1}'`
Total Items MissingorMismatch: `echo $QUERY1 | awk '{print $2}'`
Error Percentage: $QUERY2
EOF
[It appears that your bash does not recognize the $(command) syntax, so I have removed that.]
[N.B. I just tested, and Solaris's mailx sent an email formatted precisely as I typed it. If your mail reader is displaying in HTML mode, however, it may collapse whitespace and show it all as one line.]
Try to do it using \n as it is usually the standard escape sequence for a newline in a printing function., like so:
{
echo -e "Data Successfully loaded into LIP table\n"
echo -e "Total Items Purchased: `echo $QUERY1 | awk '{print $1}'\n"
echo -e "Total Items MissingorMismatch: `echo $QUERY1 | awk '{print $2}'\n"
echo -e "Error Percentage: $QUERY2\n"
} | mailx -s "Report for $DATE_YEST_FORMAT1" -r rj#host.com user2#host.com
more info can be gotten here.

Resources