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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17612004/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:14:44  来源:igfitidea点击:

Linux Shell Script: How to detect NFS Mount-point (or the Server) is dead?

linuxbashshellnfsnfsclient

提问by u775856

Generally on NFS Client, how to detect the Mounted-Point is no more available or DEAD from Server-end, by using the Bash Shell Script?

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

Normally i do:

通常我这样做:

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

But the problem is, when especially the NFS Server is totally dead or stopped, even the, lscommand, into that directory, at Client-side is hanged or died. Means, the script above is no more usable.

但问题是,尤其是当 NFS 服务器完全死机或停止时,即使是ls进入该目录的命令,在客户端也会被挂起或死机。意味着,上面的脚本不再可用。

Is there any way to detect this again please?

请问有什么办法可以再次检测到吗?

回答by Ville

"stat" command is a somewhat cleaner way:

“stat”命令是一种更简洁的方法:

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

Additionally, you can use rpcinfo to detect whether the remote nfs share is available:

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

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

Added 2013-07-15T14:31:18-05:00:

添加 2013-07-15T14:31:18-05:00:

I looked into this further as I am also working on a script that needs to recognize stale mountpoints. Inspired by one of the repliesto "Is there a good way to detect a stale NFS mount", I think the following may be the most reliable way to check for staleness of a specific mountpoint in bash:

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

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

"read -t1" construct reliably times out the subshell if stat command hangs for some reason.

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

Added 2013-07-17T12:03:23-05:00:

添加 2013-07-17T12:03:23-05:00:

Although read -t1 < <(stat -t "/my/mountpoint")works, there doesn't seem to be a way to mute its error output when the mountpoint is stale. Adding > /dev/null 2>&1either within the subshell, or in the end of the command line breaks it. Using a simple test: if [ -d /path/to/mountpoint ] ; then ... fialso works, and may preferable in scripts. After much testing it is what I ended up using.

虽然read -t1 < <(stat -t "/my/mountpoint")有效,但似乎没有办法在挂载点陈旧时将其错误输出静音。> /dev/null 2>&1在子shell中或在命令行的末尾添加会破坏它。使用简单的测试:if [ -d /path/to/mountpoint ] ; then ... fi也可以使用,并且在脚本中可能更可取。经过多次测试,这是我最终使用的。

Added 2013-07-19T13:51:27-05:00:

添加 2013-07-19T13:51:27-05:00:

A reply to my question "How can I use read timeouts with stat?" provided additional detail about muting the output of stat (or rpcinfo) when the target is not available and the command hangs for a few minutes before it would time out on its own. While [ -d /some/mountpoint ]can be used to detect a stale mountpoint, there is no similar alternative for rpcinfo, and hence use of read -t1redirection is the best option. The output from the subshell can be muted with 2>&-. Here is an example from CodeMonkey's response:

对我的问题“如何将读取超时与 stat 一起使用?”的回复提供了有关在目标不可用且命令挂起几分钟前将 stat(或 rpcinfo)的输出静音的更多详细信息,然后它会超时自己的。虽然[ -d /some/mountpoint ]可用于检测过时的挂载点,但 rpcinfo 没有类似的替代方法,因此使用read -t1重定向是最佳选择。子shell的输出可以用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

Perhaps now this question is fully answered :).

也许现在这个问题得到了充分的回答:)。

回答by et071385

The final answers give by Ville and CodeMonkey are almost correct. I'm not sure how no one noticed this, but a $REPLY string having content is a success, not a failure. Thus, an empty$REPLY string means the mount is stale. Thus, the conditional should use -z, not -n:

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

I have ran this multiple times with a valid and invalid mount point and it works. The -n check gave me reverse results, echoing the mount was stale when it was absolutely valid.

我已经使用有效和无效的挂载点多次运行它并且它有效。-n 检查给了我相反的结果,当它绝对有效时回显安装是陈旧的。

Also, the double bracket isn't necessary for a simple string check.

此外,简单的字符串检查不需要双括号。

回答by jimbolino

with "-z" I get a NFS stale but it's totaly wrong, I can accces to it and read and write a file

使用“-z”我得到一个 NFS 陈旧但它完全错误,我可以访问它并读取和写入文件