I have this bash script to check if an nfs share is mounted but its hanging on waiting for CTRL+D to be pressed for the mail part when I run it – how do I get around this?
#!/bin/bash
#set -x
mailto1=abc@test.com
#get the netapp mount point - /mnt/Netapp_NFS_Backup:
netapp_nfs_share=$(cat /etc/fstab | awk '$1 !~/#|^$|swap/ {print $2}' | sed '1,7d')
##search through "df -hPT" for the netapp mount point to see if there:
for FS in ${netapp_nfs_share)
do
df -hPT | grep -wq ${FS}
if [ $? -eq 0 ]
then
mail -s "Netapp NFS Share is mounted" $mailto1
#echo "Netapp NFS Share is mounted
else
echo "Netapp NFS share is not mounted"
fi
done
Advertisement
Answer
This is what every command which reads standard input will do if you do not provide it with standard input from another source. The usual solution is to redirect it to read from /dev/null.
mail -s "Netapp NFS Share is mounted" "$mailto1"</dev/null
However, you probably also want to fix the other antipatterns in your script. See inline comments in this refactored version.
#!/bin/bash
mailto1=abc@test.com
# avoid useless cat; refactor sed into Awk
# pipe to while read instead of using a for loop
awk '$1 !~/#|^$|swap/ && ++c > 7 {print $2}' /etc/fstab |
while read -r FS; do
# avoid useless use of if [ $? -eq 0 ]
# quote variable
if df -hPT | grep -wq "${FS}"; then
# add redirect; quote variable
mail -s "Netapp NFS Share is mounted" "$mailto1" </dev/null
else
# print diagnostics to stderr; include script name
echo "$0: Netapp NFS share is not mounted" >&2
fi
done
Pointers to more information:
- When to wrap quotes around a shell variable?
- Useless use of cat?
- Checking the success of a command in a bash `if [ .. ]` statement
- https://mywiki.wooledge.org/DontReadLinesWithFor
- Useless use of
grepandsed
The script validation tool at http://shellcheck.net/ can diagnose some, but not all, of these errors and antipatterns.
… As a further refinement, maybe only run df once and pass that to Awk, too:
if df -hPT |
awk 'BEGIN { r = 1 }
# NR is equal to FNR while we are processing the first input file, i.e. stdin from df
NR==FNR { a[++n] = $0; next }
$1 !~/#|^$|swap/ && ++c > 7 {
for (i=1; i<=n; ++i)
if ($2 ~ a[i]) {
r=0; exit r } }
END { exit r }' - /etc/fstab
then
mail -s "Netapp NFS Share is mounted" abc@test.com </dev/null
else
echo "$0: Netapp NFS share is not mounted" >&2
fi
This also illustrates exactly how the purpose of if is really just to examine the exit status of the pipeline you run as its argument.
If you can be sure that there will only ever be exactly one mounted NFS share, turning the logic around would probably allow you to simplify the final script further.