Unix/Linux Go Back    


Shell Programming and Scripting BSD, Linux, and UNIX shell scripting — Post awk, bash, csh, ksh, perl, php, python, sed, sh, shell scripts, and other shell scripting languages questions here.

Mail sent from variable is not aligned in shell script

Shell Programming and Scripting


Reply    
 
Thread Tools Search this Thread Display Modes
    #1  
Old Unix and Linux 2 Weeks Ago
viay viay is offline
Registered User
 
Join Date: May 2017
Last Activity: 23 May 2017, 8:25 AM EDT
Location: india
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Linux Mail sent from variable is not aligned in shell script

Hi Folks Linux

Scenario,

Compared two values in two different files, if file1 value is greater than the value of file2 it trigger mail,


I tried this,


Code:
echo ${usep[@]};
echo ${usep1[@]};
for i in ${!usep[@]}; do
        if [ ${usep[$i]} -gt 80 ]; then
                if [ ${usep[$i]} -gt ${usep1[$i]} ]; then
                        tmp=$(echo "Running out of space \" ${usep[$i]}\" on $(hostname) as on $(date)");
                        alertlist="$tmp";
                        echo $alertlist;
                        echo "$alertlist" | mail -s "$ORACLE_SID ALERT:  Running out of space" $maillist;
                fi
        fi
done

The issue is,

when I try


Code:
alertlist+="$tmp";

Running out of space "/u01 (99%)"
Running out of space "/u01 (99%)" Running out of space "/u02 (96%)"
Running out of space "/u01 (99%)" Running out of space "/u02 (96%)" Running out of space "/u03 (90%)"

It append the values in variable, and sent the mail entirely in a single line.

Meanwhile when I try


Code:
alertlist="$tmp";

Running out of space "/u01 (99%)"
Running out of space "/u02 (96%)"
Running out of space "/u03 (90%)"

it looks good but it sent the mail for each mount point separately, which I receive individually 3 times.


I need to receive a mail which all mount point contain above 80 in single mail.
How can I do that?

Last edited by vgersh99; 2 Weeks Ago at 12:57 PM.. Reason: code tags, please!
Sponsored Links
    #2  
Old Unix and Linux 2 Weeks Ago
Don Cragun's Unix or Linux Image
Don Cragun Don Cragun is offline Forum Staff  
Administrator
 
Join Date: Jul 2012
Last Activity: 29 May 2017, 4:14 AM EDT
Location: San Jose, CA, USA
Posts: 10,309
Thanks: 521
Thanked 3,587 Times in 3,055 Posts
I have no idea what your usep and usep1 arrays are supposed to contain, but it is obvious that the code you have shown us can't possibly produce the output you say you are getting. Both of those arrays need to contain numeric values for your code to work and there is nothing in your code that prints the filesystem names if both of those arrays contain numeric values???

It would seem that you want to
  1. take the mail command out of the loop,
  2. initialize alertlist to an empty string before you start your loop,
  3. use echo "$tmp" inside the loop,
  4. add the contents of the variable tmp as an additional line in the variable alertlist inside the loop, and
  5. after falling off the end of the loop, send mail if and only if ${#alertlist} is non-zero.
Sponsored Links
    #3  
Old Unix and Linux 2 Weeks Ago
viay viay is offline
Registered User
 
Join Date: May 2017
Last Activity: 23 May 2017, 8:25 AM EDT
Location: india
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
First of all thanks for response,

This is my entire code, you can find more details here.


Code:
export maillist=123@gmail.com;
#df -PH /d04 /d05 /u01 /export | grep -vE '^Filesystem|none|cdrom'|awk '{ print $5 " " $6 }' | while read output;
#df -PH | grep -vE '^Filesystem|none|cdrom|swdepot'|awk '{ print $5 " " $6 }' > diskcheck.log;

#diskcheck is current output whereas disk_alert is previous runned output

if [ -s "$/monitor/log/disk_alert.log" ]; then
#Getting variables and compare with old
  usep=($(cat $/monitor/diskcheck.log | awk '{ print $1 }' | cut -d'%' -f1));
  partitions=($(cat $/monitor/diskcheck.log | awk '{ print $2 }' ));
  usep1=($(cat $/monitor/log/disk_alert.log | awk '{ print $1 }' | cut -d'%' -f1));
else
   cat "$/monitor/diskcheck.log" > "/monitor/log/disk_alert.log";
  usep=($(cat $/monitor/diskcheck.log | awk '{ print $1 }' | cut -d'%' -f1));
  partitions=($(cat $/monitor/diskcheck.log | awk '{ print $2 }' ));
  usep1=($(cat $/monitor/log/disk_alert.log | awk '{ print $1 }' | cut -d'%' -f1));
fi

echo ${usep[@]};
echo ${usep1[@]};
alertlist()
# index = i
for i in ${!usep[@]}; do
        if [ ${usep[$i]} -gt 80 ]; then
                if [ ${usep[$i]} -gt ${usep1[$i]} ]; then
                        #mail=awk '{ ${usep[$i]} print $0 }' $/monitor/diskcheck.log;
                        # Temp to store current percentage diff and partition to store in a variable.
                        tmp="$(echo -e "Running out of space \"${partitions[$i]} (${usep[$i]}%)\" on $(hostname) as on $(date)")";
                        #tmp=$(printf "%s\n" "(${usep[$i]}%) percent used on ${partitions[$i]}");
                        #alertlist holds the values to send mail.
                        #alertlist+="$tmp";
                        echo "$tmp"
                        echo "$tmp" | mail -s "ALERT:  Running out of space" $maillist;
                        #echo "Running out of space \"${partitions[$i]} (${usep[$i]}%)\" on $(hostname) as on $(date)";
                fi
        fi
done
#echo "$alertlist" | mail -s "ALERT:  Running out of space" $maillist;


those arrays contain numeric values???
yes, arrays only contain numeric values.

1.take the mail command out of the loop,
Yes, I've tried that But it print only the last value of variable(alertlist)

2.initialize alertlist to an empty string before you start your loop,
Yes, tried it but won't work

3.use echo "$tmp" inside the loop,
Echo looks good while inside loop

4.add the contents of the variable tmp as an additional line in the variable alertlist inside the loop
I think it is similar as previous one, Right?

Have a look at the summary.

Thanks

Last edited by Don Cragun; 2 Weeks Ago at 02:38 PM.. Reason: Add CODE and ICODE tags.
    #4  
Old Unix and Linux 2 Weeks Ago
Don Cragun's Unix or Linux Image
Don Cragun Don Cragun is offline Forum Staff  
Administrator
 
Join Date: Jul 2012
Last Activity: 29 May 2017, 4:14 AM EDT
Location: San Jose, CA, USA
Posts: 10,309
Thanks: 521
Thanked 3,587 Times in 3,055 Posts
Please show us the code where you tried what I suggested in post #2 in this thread. Steps 1, 2, 4, and 5 of what I suggested do not appear in the code you showed us in post #3.

The code that you did show us in post #3 defines a function named alertlist whose body depends on what shell you're using (probably either the nested for loop in your code, a syntax error, or a comment) and which is never invoked in your script.

What operating system and shell are you using?

Do you really have a directory named $ in the directory in which you run this script? Using a name like that is certainly possible, but using it can frequently be accident prone. (Or does $/ have some special meaning in the shell you're using?)
Sponsored Links
    #5  
Old Unix and Linux 1 Week Ago
viay viay is offline
Registered User
 
Join Date: May 2017
Last Activity: 23 May 2017, 8:25 AM EDT
Location: india
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Hello Don,

sorry for late response I was out of my location, Here I've attached code as you suggested and updated,

1.) Please show us the code where you tried what I suggested in post #2 in this thread. Steps 1, 2, 4, and 5 of what I suggested do not appear in the code you showed us in post #3.



Code:
export maillist=abc@gmail.com;
#df -PH /d04 /d05 /u01 /export | grep -vE '^Filesystem|none|cdrom'|awk '{ print $5 " " $6 }' | while read output;
df -PH | grep -vE '^Filesystem|none|cdrom|swdepot'|awk '{ print $5 " " $6 }' > $HOME/monitor/log/diskcheck.log;

#diskcheck is current output whereas disk_alert is previous runned output

if [ -s "$HOME/monitor/log/disk_alert.log" ]; then
#Getting variables and compare with old
  usep=($(cat $HOME/monitor/diskcheck.log | awk '{ print $1 }' | cut -d'%' -f1));
  partitions=($(cat $HOME/monitor/diskcheck.log | awk '{ print $2 }' ));
  usep1=($(cat $HOME/monitor/log/disk_alert.log | awk '{ print $1 }' | cut -d'%' -f1));
else
   cat "$HOME/monitor/diskcheck.log" > "$HOME/monitor/log/disk_alert.log";
  usep=($(cat $HOME/monitor/diskcheck.log | awk '{ print $1 }' | cut -d'%' -f1));
  partitions=($(cat $HOME/monitor/diskcheck. | awk '{ print $2 }' ));
  usep1=($(cat $HOME/monitor/log/disk_alert.log | awk '{ print $1 }' | cut -d'%' -f1));
fi

echo ${usep[@]};
echo ${usep1[@]};
alertlist=''
# index = i
for i in ${!usep[@]}; do
        if [ ${usep[$i]} -gt 80 ]; then
                if [ ${usep[$i]} -gt ${usep1[$i]} ]; then
                        # Temp to store current percentage diff and partition to store in a variable.
                        tmp="$(echo -e "Running out of space \"${partitions[$i]} (${usep[$i]}%)\" on $(hostname) as on $(date)")";
                        echo "$tmp"
                        #tmp=$(printf "%s\n" "(${usep[$i]}%) percent used on ${partitions[$i]}");
                        alertlist+="$tmp";

                fi
        fi
done
if [ ! -z "${alertlist}" ]; then
        echo "${alertlist}" | mail -s "ALERT:  Running out of space" $maillist;
fi

a.) use echo "$tmp" inside the loop! the result is


Code:
19 1 39 3 90 83 1 14 96
19 1 39 3 40 83 1 14 66
Running out of space "/u05 (90%)" on localhost.local as on Mon May 15
Running out of space "/u02 (96%)" on localhost.local as on Mon May 15

b.) The code that you did show us in post #3 defines a function named alertlist whose body depends on what shell you're using!
bash_version 4.1.2(1)-release

and finally the output of above script is


Code:
Running out of space "/d01 (90%)" on localhost.local as on Mon May 15 Running out of space "/patches (96%)" onlocalhost.local as on Mon May 15

all it shows in a single line, but echo of "$tmp" variable is stored clear. But I need mail which contains information as it's stored in "$tmp" with proper alignment, Because now 2 of the mount points only passed our condition if it was more than 10 it's very complex to understand.

2.)What operating system and shell are you using?
RHEL 6.8
bash_version 4.1.2(1)-release

3.)Do you really have a directory named $ in the directory in which you run this script?
it refers the directory where the files are located, it's actually $HOME/monitor/
$HOME is home directory of username in my case username is vijay,
So

Code:
vijay/monitor

4.)Or does $/ have some special meaning in the shell you're using?
No, it redirect to the directory called $HOME/monitor. in post #1 I conclude that information.

Hope this will help.
[mod]Please use CODE tags as required by forum rules!

Last edited by Don Cragun; 1 Week Ago at 07:34 PM.. Reason: Add CODE and ICODE tags.
Sponsored Links
    #6  
Old Unix and Linux 1 Week Ago
Don Cragun's Unix or Linux Image
Don Cragun Don Cragun is offline Forum Staff  
Administrator
 
Join Date: Jul 2012
Last Activity: 29 May 2017, 4:14 AM EDT
Location: San Jose, CA, USA
Posts: 10,309
Thanks: 521
Thanked 3,587 Times in 3,055 Posts
Try changing your script to:

Code:
export maillist=abc@gmail.com;
#df -PH /d04 /d05 /u01 /export | grep -vE '^Filesystem|none|cdrom'|awk '{ print $5 " " $6 }' | while read output;
df -PH | grep -vE '^Filesystem|none|cdrom|swdepot'|awk '{ print $5 " " $6 }' > $HOME/monitor/log/diskcheck.log;

#diskcheck is current output whereas disk_alert is previous runned output

if [ -s "$HOME/monitor/log/disk_alert.log" ]; then
#Getting variables and compare with old
  usep=($(cat $HOME/monitor/diskcheck.log | awk '{ print $1 }' | cut -d'%' -f1));
  partitions=($(cat $HOME/monitor/diskcheck.log | awk '{ print $2 }' ));
  usep1=($(cat $HOME/monitor/log/disk_alert.log | awk '{ print $1 }' | cut -d'%' -f1));
else
   cat "$HOME/monitor/diskcheck.log" > "$HOME/monitor/log/disk_alert.log";
  usep=($(cat $HOME/monitor/diskcheck.log | awk '{ print $1 }' | cut -d'%' -f1));
  partitions=($(cat $HOME/monitor/diskcheck. | awk '{ print $2 }' ));
  usep1=($(cat $HOME/monitor/log/disk_alert.log | awk '{ print $1 }' | cut -d'%' -f1));
fi

echo ${usep[@]};
echo ${usep1[@]};
unset alertlist
# index = i
for i in ${!usep[@]}; do
        if [ ${usep[$i]} -gt 80 ]; then
                if [ ${usep[$i]} -gt ${usep1[$i]} ]; then
                        # Temp to store current percentage diff and partition to store in a variable.
                        tmp="$(echo -e "Running out of space \"${partitions[$i]} (${usep[$i]}%)\" on $(hostname) as on $(date)")";
                        echo "$tmp"
                        #tmp=$(printf "%s\n" "(${usep[$i]}%) percent used on ${partitions[$i]}");
                        alertlist=("${alertlist[@]" "$tmp")
                fi
        fi
done
if [ ${#alertlist} -gt 0 ]; then
        printf '%s\n' "${alertlist[@]}" | mail -s "ALERT:  Running out of space" $maillist;
        echo "Following text sent as body of mail to $maillist:"
        printf '%s\n' "${alertlist[@]}"
fi

and tell us what happens.

Note, however, that if a mounted filesystem is ever unmounted or a new filesystem is mounted between runs of your script, there is no guarantee that the order of the percentage values stored in the arrays usep and usep1 are in the same order. And note that if $HOME/monitor/log/disk_alert.log is not the name of an existing file whose size is larger than 0, the assignment to the partitions array will fail since you're reading the file diskcheck. instead of diskcheck.log:

Code:
  partitions=($(cat $HOME/monitor/diskcheck. | awk '{ print $2 }' ));

and all of your assignments like this are wasting CPU and memory by using cat when it is not needed. Try:

Code:
  partitions=($(awk '{ print $2 }' $HOME/monitor/diskcheck.log));

instead.
Sponsored Links
    #7  
Old Unix and Linux 1 Week Ago
viay viay is offline
Registered User
 
Join Date: May 2017
Last Activity: 23 May 2017, 8:25 AM EDT
Location: india
Posts: 5
Thanks: 0
Thanked 0 Times in 0 Posts
Hello Don,

As you suggest I tried the new script,

a.)all of your assignments like this are wasting CPU and memory by using cat when it is not needed. Try:
Yes


Code:
export maillist=abc@gmail.com;
#df -PH /d04 /d05 /u01 /export | grep -vE '^Filesystem|none|cdrom'|awk '{ print $5 " " $6 }' | while read output;
df -PH | grep -vE '^Filesystem|none|cdrom|swdepot'|awk '{ print $5 " " $6 }' > $HOME/monitor/diskcheck.log;

if [ -s "$HOME/monitor/log/disk_alert.log" ]; then
#Getting variables and compare with old
  usep=($(awk '{ print $1 }' $HOME/monitor/diskcheck.log | cut -d'%' -f1));
  partitions=($(awk '{ print $2 }' $HOME/monitor/diskcheck.log | cut -d'%' -f1));
  usep1=($(awk '{ print $1 }' $HOME/monitor/log/disk_alert.log | cut -d'%' -f1));
else
   cat "$HOME/monitor/diskcheck.log" > "$HOME/monitor/log/disk_alert.log";
  usep=($(awk '{ print $1 }' $HOME/monitor/diskcheck.log | cut -d'%' -f1));
  partitions=($(awk '{ print $2 }' $HOME/monitor/diskcheck.log | cut -d'%' -f1));
  usep1=($(awk '{ print $1 }' $HOME/monitor/log/disk_alert.log | cut -d'%' -f1));
fi

echo ${usep[@]};
echo ${usep1[@]};
unset alertlist
# index = i
for i in ${!usep[@]}; do
        if [ ${usep[$i]} -gt 80 ]; then
                if [ ${usep[$i]} -gt ${usep1[$i]} ]; then
                        # Temp to store current percentage diff and partition to store in a variable.
                        tmp="$(echo -e "Running out of space \"${partitions[$i]} (${usep[$i]}%)\" on $(hostname) as on $(date)")";
                        echo "$tmp"
                        #tmp=$(printf "%s\n" "(${usep[$i]}%) percent used on ${partitions[$i]}");
                        alertlist=("${alertlist[@]}" "$tmp")
                fi
        fi
done

if [ ${#alertlist} -gt 0 ]; then
        printf '%s\n' "${alertlist[@]}" | mail -s "ALERT:  Running out of space" $maillist;
        echo "Following text sent as body of mail to $maillist:"
        printf '%s\n' "${alertlist[@]}"
fi                     #alertlist holds the values to send mail.

While I run the script it seems everything okay as usual the output of run script is,

Code:
[vijay@localhost monitor]$ sh disk_alert.sh
19 1 39 3 40 93 1 14 96
19 1 39 3 40 83 1 14 66
Running out of space "/u05 (93%)" on localhost.local as on Tue May 16 
Running out of space "/u02 (96%)" on localhost.local as on Tue May 16 
Following text sent as body of mail to abc@gmail.com:
Running out of space "/u05 (93%)" on localhost.local as on Tue May 16 
Running out of space "/u02 (96%)" on localhost.local as on Tue May 16

When I receive the mail it's remains with the old format

Code:
Running out of space "/u05 (93%)" on localhost.local as on Tue May 16 Running out of space "/u02 (96%)" on localhost.local as on Tue May 16

1.)
Note, however, that if a mounted filesystem is ever unmounted or a new filesystem is mounted between runs of your script, there is no guarantee that the order of the percentage values stored in the arrays usep and usep1 are in the same order!

Is their any solution for this?
Sponsored Links
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Linux More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Unable to pass shell script variable to awk command in same shell script Ashunayak Shell Programming and Scripting 2 01-27-2014 12:04 PM
Shell Script To E-Mail SalientAnimal Shell Programming and Scripting 14 11-16-2012 03:41 AM
How to send e-mail from shell script ( C shell )? arukuku UNIX for Dummies Questions & Answers 2 04-20-2012 06:19 AM
Mail shell script rgumm Shell Programming and Scripting 3 06-15-2010 05:35 AM
assign awk's variable to shell script's variable? tiger2000 Shell Programming and Scripting 4 04-13-2010 03:53 PM



All times are GMT -4. The time now is 07:33 AM.