Linuxshell脚本:如何检测NFS挂载点(或服务器)已经死了?

通常在NFS客户端上,如何使用Bash Shell脚本检测挂载点不再可用或从服务器端DEAD

通常我做:

if ls '/var/data' 2>&1 | grep 'Stale file handle'; then echo "failing"; else echo "ok"; fi 

但问题是,特别是当NFS服务器完全死亡或停止,甚至是, ls命令进入该目录时,客户端被挂起或死亡。 意思是,上面的脚本不再可用。

有什么办法可以再检测一次吗?

“统计”命令是一个更清洁的方式:

 statresult=`stat /my/mountpoint 2>&1 | grep -i "stale"` if [ "${statresult}" != "" ]; then #result not empty: mountpoint is stale; remove it umount -f /my/mountpoint fi 

此外,您可以使用rpcinfo来检测远程nfs共享是否可用:

 rpcinfo -t remote.system.net nfs > /dev/null 2>&1 if [ $? -eq 0 ]; then echo Remote NFS share available. fi 

新增2013-07-15T14:31:18-05:00:

我进一步研究了这一点,因为我也在研究需要识别陈旧挂载点的脚本。 受到“是否有一个很好的方法来检测过时的NFS挂载” 的答复的启发,我认为以下可能是最可靠的方法来检查bash中的特定挂载点的过时:

 read -t1 < <(stat -t "/my/mountpoint") if [ $? -eq 1 ]; then echo NFS mount stale. Removing... umount -f -l /my/mountpoint fi 

如果stat命令由于某种原因挂起,那么“read -t1”构造可靠地超时了子shell。

新增2013-07-17T12:03:23-05:00:

尽管read -t1 < <(stat -t "/my/mountpoint")工作,但是当挂载点过期时,似乎没有办法使其错误输出静音。 在子外壳中添加> /dev/null 2>&1 ,或者在命令行的末尾添加> /dev/null 2>&1 。 使用一个简单的测试: if [ -d /path/to/mountpoint ] ; then ... fi if [ -d /path/to/mountpoint ] ; then ... fi也可以工作,并可能在脚本中更好。 经过多次测试,这是我最终使用的。

新增2013-07-19T13:51:27-05:00:

回答我的问题“ 如何使用stat读取超时? ”提供了关于在目标不可用时将stat(或rpcinfo)的输出静音的更多细节,并且该命令在超时之前挂起几分钟拥有。 虽然可以使用[ -d /some/mountpoint ]来检测过时的挂载点,但rpcinfo没有类似的选择,因此使用read -t1重定向是最好的选择。 从subhell的输出可以用2>& –静音。 下面是CodeMonkey响应的一个例子:

 mountpoint="/my/mountpoint" read -t1 < <(stat -t "$mountpoint" 2>&-) if [[ -n "$REPLY" ]]; then echo "NFS mount stale. Removing..." umount -f -l "$mountpoint" fi 

也许现在这个问题已经完全回答了:)。

Ville和CodeMonkey提供的最终答案几乎是正确的。 我不知道如何没有人注意到这一点,但有一个$ REPLY字符串的内容是成功的 ,而不是失败。 因此,一个空的 $ REPLY字符串意味着挂载是陈旧的。 因此,条件应该使用-z,而不是-n:

 mountpoint="/my/mountpoint" read -t1 < <(stat -t "$mountpoint" 2>&-) if [ -z "$REPLY" ] ; then echo "NFS mount stale. Removing..." umount -f -l "$mountpoint" fi 

我已经多次运行这个有效和无效的挂载点,它的工作原理。 -n检查给了我相反的结果,回应挂载是绝望的,当它是绝对有效的。

而且,对于简单的字符串检查,双括号不是必需的。