How can I use bash to gather all NFS mount points with multiple configuration files to check that each mount is writeable?
I am trying to create a script that will dynamically find all NFS mount points that should be writable and check that they are still writable however I can’t seem to get my head around connecting the mounts to their share directories.
So for example I have a server’s /etc/auto.master like this (I’ve sanitized some of the data):
/etc/auto.master /nfs1 /etc/auto.nfs1 --ghost /nfs2 /etc/auto.nfs2 --ghost
And each of those files has:
/etc/auto.nfs1 home -rw,soft-intr -fstype=nfs server1:/shared/home store -rw,soft-intr -fstype=nfs server2:/shared/store /etc/auto.nfs2 data -rw,soft-intr -fstype=nfs oralceserver1:/shared/data rman -rw,soft-intr -fstype=nfs oracleserver1:/shared/rman
What I’m trying to get out of that is
/nfs1/home /nfs1/store /nfs2/data /nfs2/rman
without getting any erroneous or commented entries caught in the net.
My code attempt is this:
#!/bin/bash for automst in `grep '^/' /etc/auto.master|awk -F" " '{for(i=1;i<=NF;i++){if ($i ~ /etc/){print $i}}}'`; do echo $automst > /tmp/auto.mst done AUTOMST=`cat /tmp/auto.mst` for mastermount in `grep '^/' /etc/auto.master|awk -F" " '{for(i=1;i<=NF;i++){if ($i ~ /etc/){print $i}}}'`; do grep . $mastermount|grep -v '#'|awk {'print $1'}; done > /tmp/nfsmounteddirs for dir in `cat /tmp/nfsmounteddirs`; do if [ -w "$dir" ]; then echo "$dir is writeable"; else echo "$dir is not writeable!";fi done
I have 600 Linux servers and many have their own individual NFS setups and we don’t have an alerting solution in place that can check, and while having all those individual scripts would be “a” solution, it would be a nightmare to manage and a lot of work so the dynamic aspect of it would be very useful.
Answer
awk '/^// { # Process where lines begin with a / fil=$2; # Track the file name nfs=$1 # Track the nfs while (getline line < fil > 0) { # Read the fil specified by fil till the end of the file split(line,map,","); # Split the lines in array map with , as the delimiter split(map[1],map1,/[[:space:]]+/); # Further split map into map1 with spaces as the delimiter if(map1[2]~/w/ && line !~ /^#/) { print nfs" "map1[1] # If w is in the permissions string and the line doesn't begin with a comment, print the nfs and share } } close(fil) # Close the file after we have finished reading }' /etc/auto.master
One liner:
awk '/^// { fil=$2;nfs=$1;while (getline line < fil > 0) { split(line,map,",");split(map[1],map1,/[[:space:]]+/);if(map1[2]~/w/ && line !~ /^#/) { print nfs" "map1[1] } } close(fil) }' /etc/auto.master
Output:
/nfs1 home /nfs1 store /nfs2 data /nfs2 rman