i am able to send mail of simple test in Linux
echo "body" | mail -s "test" xxx#yahoo.com
but below code is not working
#!/bin/bash
VAR1=$(df / | grep / | awk '{ print $5}' | sed 's/%//g')
VAR2=$(df /dev/sda1 | grep /dev/sda1 | awk '{ print $5}' | sed 's/%//g')
VAR3=$(df /dev/mapper/centos-var | grep /dev/mapper/centos-var | awk '{ print $5}' | sed 's/%//g')
THRESHOLD=50
TODAY=$(date)
if [ "$VAR1" -gt "$THRESHOLD" ] ; then
mail -s 'Disk Space Alert' rupendra#3ess.in << EOF
Date of $TODAY
Your system partition remaining free space is critically low.
/ partition used is $VAR1%
/ usr partition used is $VAR2%
/ var partition used is $VAR3%
What error did you receive?
The following one worked for me,
#!/bin/bash
set -x
VAR1=$(df / | grep / | awk '{ print $5}' | sed 's/%//g')
VAR2=$(df /dev/sda1 | grep /dev/sda1 | awk '{ print $5}' | sed 's/%//g')
VAR3=$(df /dev/mapper/centos-var | grep /dev/mapper/centos-var | awk '{ print $5}' | sed 's/%//g')
THRESHOLD=50
TODAY=$(date)
echo "VAR1=$VAR1, THRESHOLD=$THRESHOLD"
if [ "$VAR1" -gt "$THRESHOLD" ] ; then
mail -s 'Disk Space Alert' abcd#xyz.com << EOF
Date of $TODAY
Your system partition remaining free space is critically low.
/ partition used is $VAR1%
/ usr partition used is $VAR2%
/ var partition used is $VAR3%
EOF
fi
I have my filesystem as like below
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rootvg-rootvol
20G 3.7G 15G 20% /
tmpfs 71G 8.0K 71G 1% /dev/shm
And my code is as below:
varone = df -h | awk ' {print $1 }'
vartwo = df -h | awk ' NR == 2 {print $2","$3","$4","$5","$6 }'
echo "$varone $vartwo" >> /home/jeevagan/test_scripts/sizes/excel.csv
I want to export the 'df -h' into a csv file. Why I printed $1 alone in one variable means, there is space in the 'df -h' output. I want it to be printed in a single line.
When I run the script, it throws an error like
varone: command not found
vartwo: command not found
You can't put spaces around the equal sign, and you need backquotes to put the result of your command in a variable.
Try this:
varone=`df -h | awk ' {print $1 }'`
vartwo=`df -h | awk ' NR == 2 {print $2","$3","$4","$5","$6 }'`
echo "$varone $vartwo" >> /home/jeevagan/test_scripts/sizes/excel.csv
If you just wanted to capture df -h
varOne=`df -h -P| awk '{print $1","$2","$3","$4","$5","$6 }'`
echo "$varOne" >> /home/jeevagan/test_scripts/sizes/excel.csv
Read about 'P' here
How can I *only* get the number of bytes available on a disk in bash?
My script is as below. When we run the script, it automatically saves the disk space usage in separate cells.
SIZES_1=`df -h | awk 'FNR == 1 {print $1","$2","$3","$4","$5","$6}'`
SIZES_2=`df -h | awk 'FNR == 2 {print $1","$2","$3","$4","$5","$6}'`
SIZES_3=`df -h | awk 'FNR == 3 {print $1","$2","$3","$4","$5","$6}'`
SIZES_4=`df -h | awk 'FNR == 4 {print $1","$2","$3","$4","$5","$6}'`
SIZES_5=`df -h | awk 'FNR == 5 {print $1","$2","$3","$4","$5","$6}'`
SIZES_6=`df -h | awk 'FNR == 6 {print $1","$2","$3","$4","$5","$6}'`
SIZES_7=`df -h | awk 'FNR == 7 {print $1","$2","$3","$4","$5","$6}'`
SIZES_8=`df -h | awk 'FNR == 8 {print $1","$2","$3","$4","$5","$6}'`
echo `date +%Z-%Y-%m-%d_%H-%M-%S` >>/home/jeevagan/test_scripts/sizes/excel.csv
echo "$SIZES_1" >> /home/jeevagan/test_scripts/sizes/excel.csv
echo "$SIZES_2" >> /home/jeevagan/test_scripts/sizes/excel.csv
echo "$SIZES_3" >> /home/jeevagan/test_scripts/sizes/excel.csv
echo "$SIZES_4" >> /home/jeevagan/test_scripts/sizes/excel.csv
echo "$SIZES_5" >> /home/jeevagan/test_scripts/sizes/excel.csv
echo "$SIZES_6" >> /home/jeevagan/test_scripts/sizes/excel.csv
echo "$SIZES_7" >> /home/jeevagan/test_scripts/sizes/excel.csv
echo "$SIZES_8" >> /home/jeevagan/test_scripts/sizes/excel.csv
This script is okay for my machine.
My doubt is, if somebody else's machine has many file systems, my script won't work to fetch all the file systems usage. How to make it to grab all those automatically?
Assuming you want all filesystems you can simplify that to:
printf '%s\n' "$(date +%Z-%Y-%m-%d_%H-%M-%S)" >> excel.csv
df -h | awk '{print $1","$2","$3","$4","$5","$6}' >> excel.csv
I would simplify this to
{ date +%Z-%F_%H-%M-%S; df -h | tr -s ' ' ','; } >> excel.csv
Group commands so only a single redirect is needed
Squeeze spaces and replace them with a single comma using tr
No need for echo `date` or similar: it's the same as just date
date +%Y-%m-%d is the same as date +%F
Notice that this has a little flaw in that the first line of the output of df -h, which looks something like this originally
Filesystem Size Used Avail Use% Mounted on
has a space in the heading of the last column, so it becomes
Filesystem,Size,Used,Avail,Use%,Mounted,on
with an extra comma. The original awk solution just cut off the last word of the line, though. Similarly, spaces in paths would trip up this solution.
To fix the comma problem, you could for example run
sed -i 's/Mounted,on$/Mounted on/' excel.csv
every now and so often.
As an aside, to replace all field separators in awk, instead of
awk '{print $1","$2","$3","$4","$5","$6}'
you can use
awk 'BEGIN { OFS = "," } { $1 = $1; print }'
or, shorter,
awk -v OFS=',' '{$1=$1}1'
I am trying to write a shell script to monitor file system. script logic is,
for each file system from df -H command, read the file system threshold file and get the critical threshold, warning threshold. Based on the condition, it will send notification.
Here is my script:
#!/bin/sh
df -H | grep -vE '^Filesystem|none|boot|tmp|tmpfs' | awk '{ print $5 " " $6 }' | while read $output
do
echo $output
fsuse=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 )
fsname=$(echo $output | awk '{ print $2 }' )
server=`cat /workspace/OSE/scripts/fs_alert|grep -w $fsname|awk -F":" '{print $2}'`
fscrit=`cat /workspace/OSE/scripts/fs_alert|grep -w $fsname|awk -F":" '{print $3}'`
fswarn=`cat /workspace/OSE/scripts/fs_alert|grep -w $fsname|awk -F":" '{print $4}'`
serenv=`cat /workspace/OSE/scripts/fs_alert|grep -w $fsname|awk -F":" '{print $5}'`
if [ $fsuse -ge $fscrit ]; then
message="CRITICAL:${server}:${serenv}:$fsname Is $fsuse Filled"
_notify;
elif [ $fsuse -gt $fswarn ] && [ $fsuse -lt $fscrit ]; then
message="WARNING: $fsname is $fsuse Filled"
_notify;
else
echo "File system space looks good"
fi
done
Here is /workspace/OSE/scripts/fs_alert:
/:hlpdbq001:90:80:QA:dba_mail
/dev/shm:hlpdbq001:90:80:QA:dba_mail
/boot:hlpdbq001:90:80:QA:dba_mail
/home:hlpdbq001:90:80:QA:dba_mail
/opt:hlpdbq001:90:80:QA:dba_mail
/opt/security:hlpdbq001:90:80:QA:dba_mail
/tmp:hlpdbq001:90:80:QA:dba_mail
/var:hlpdbq001:90:80:QA:dba_mail
/u01/app:hlpdbq001:90:80:QA:dba_mail
/u01/app/oracle:hlpdbq001:90:80:QA:dba_mail
/oratrace:hlpdbq001:90:80:QA:dba_mail
/u01/app/emagent:hlpdbq001:90:80:QA:dba_mail
/gg:hlpdbq001:90:80:QA:dba_mail
/workspace:hlpdbq001:90:80:QA:dba_mail
/dbaudit:hlpdbq001:90:80:QA:dba_mail
/tools:hlpdbq001:90:80:QA:dba_mail
My problem is when the script is trying to get crit_va, warn_val from the file for /u01 file system, I am getting three results. How do I get/filter one file system at a time?
$ df -H|grep /u01
/dev/mapper/datavg-gridbaselv 53G 12G 39G 24% /u01/app
/dev/mapper/datavg-rdbmsbaselv 53G 9.6G 41G 20% /u01/app/oracle
/dev/mapper/datavg-oemagentlv 22G 980M 20G 5% /u01/app/emagent
what is the best way to handle this issue?
do i need logic based on Filesystem or Mounted on.
Don't reinvent the wheel. There are tools out there that can do this for your. Try monit for example:
http://sysadminman.net/blog/2011/monit-disk-space-monitoring-1716
well, monit is fine ), if you need alternative take a look at df-check - a wrapper for df utility to verify that thresholds are not exceeded , on per partition basis. At least it seems very close to what you started to implement in your bash script, but it's written on perl and has a neat and simple installation layout. ready to use tool.
-- Regards
PS discloser - I am the tool author
I've written a function to do some logging on different aspects of the files, folder, etc and I 'm going to have this automatically email members of my staff. All this is fine but I wouldn't mind some pointers and help to make the formation nicer - this will get sent out via mailutils as part of the script.
Just looking for some nice spacing tips,etc
function report(){
lsb_release -a
echo "OS: $(uname -s)"
echo "ARCH: $(uname -m)"
echo "VER: $(uname -r)"
echo "Apache running "
ps aux|grep -i apache2
echo "Showing if SSL is open"
apache2ctl -M | grep ssl
echo "Space on local disk"
df -h
echo "Showing permissions for the web folders"
echo $'*** /var/www// ***'
ls -l /var/www | awk '{print $1 " " $3 " " $4 " " $9}'
ls -l /var/www/user1 | awk '{print $1 " " $3 " " $4 " " $9}'
ls -l /var/www/user2 | awk '{print $1 " " $3 " " $4 " " $9}'
echo "Showing network status"
ifconfig eth0
echo " DNS "
tail /etc/resolv.conf
echo "Current workspaces set up on the local server "
grep user2 /var/www/temp/text.txt | grep -E -o '[0-9]+[0-9]'
}
Try piping the "column" command instead of or after using awk or cut.
ls -l | awk '{print $1" "$3" "$4" "$9}' | tail -n +2 | column -t
Check out the difference between "mount" and "mount | column -t" or "df -PH and df -PH | column -t"
If you want to concatenate columns of info with the same number or relational fields you can use process redirection and "paste."
paste -d ' ' <(cat /sys/class/scsi_host/host*/device/fc_host:host*/port_name) \
<(cat /sys/class/scsi_host/host*/device/fc_host:host*/speed) \
<(cat /sys/class/scsi_host/host*/device/fc_host:host*/port_state)
0x218000e05a0001aa 4 Gbit Online
0x218000e05a2001aa 4 Gbit Online