0

我有以下代码:

#!/bin/bash

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

如何静音 stat 的输出,同时仍然能够在后续测试中检测到其错误级别?

在子外壳内添加>/dev/null 2>&1,或在读取行的末尾添加不起作用。但一定有办法...

感谢您对此的任何见解!

4

2 回答 2

3

使用命令替换,而不是进程替换

不要从进程替换中读取,而是考虑使用命令替换。例如:

mountpoint=$(stat -t "/my/mountpoint" 2>&1)

这将通过将标准输出存储在变量中来使输出静音,但可以通过取消引用$mountpoint来检索结果。这种方法还可以通过$?访问退出状态。.

更清晰的选择

或者,您可以更简单地将其重写为:

mountpoint="/my/mountpoint"
if stat -t "$mountpoint" 2>&-
then
    echo "NFS mount stale. Removing..."
    umount -f -l "$mountpoint"
fi

对我来说,这似乎更能揭示意图,更不容易出错,但你的里程肯定会有所不同。

(Ab) 使用读取超时

在评论中,OP 询问是否可以滥用读取超时来处理来自stat的挂起输入。答案是肯定的,如果你关闭标准错误并检查一个空的$REPLY字符串。例如:

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

这有几个原因:

  1. 在 Bash 中使用read内置时:

    如果没有提供 NAME,则读取的行存储在 REPLY 变量中。

  2. 关闭标准错误后,$REPLY将为空,除非stat在标准输出上返回某些内容,如果遇到错误则不会。换句话说,您正在检查$REPLY字符串的内容,而不是read的退出状态。

于 2013-07-19T17:07:02.950 回答
0

我想我明白了!您的回复中提到的重定向似乎在子shell中起作用,而不会像 2>&1 那样清除返回码。所以这可以按预期工作:

read -t1 < <(rpcinfo -t 10.0.128.1 nfs 2>&-)
if [ $? -eq 0 ]; then
  echo "NFS server/service available!"
else
  echo "NFS server/service unavailable!"
fi

其中 10.0.128.1 是一个“坏”IP(没有服务器/服务响应)。脚本在一秒钟内超时并产生“NFS 服务器/服务不可用!” 响应,但 rpcinfo 没有输出。同样,当 IP 良好时,输出所需的响应。

我赞成你的回应!

于 2013-07-19T18:42:47.933 回答