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
grep
andsed
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.