Skip to content
Advertisement

mail -s waiting for CTRL+D in bash script

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:

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.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement