2013-09-26 45 views
2

如果我执行了以下操作,并且网络已关闭,则会执行零个案例,而不应该这样做。今天通过SSH检查通过命令输出的零线

case "$(ssh -n $host zfs list -t snapshot -o name -H | grep "tank/fs" | wc -l | awk '{print $1}')" in 
    0) # do something 
     ;; 
    1) # do something else 
     ;; 
    *) # fail 
esac 

在我检查,我可以ssh来$host脚本较早,但我发现这个问题,去哪儿网我的支票后立即失败。

如果我检查SSH命令的返回值,那么我将始终从awk获取返回值,因为它将在最后执行。

问题

如何确保我其实算零线即zfs输出,而不是零线从失败的SSH连接?

回答

1

说:

set -o pipefail 

在脚本(或case语句之前)的开始。

set -o pipefail 
$value=$(ssh -n $host zfs list -t snapshot -o name -H | grep "tank/fs" | wc -l | awk '{print $1}') 
if [ $? == 0 ]; then 
    case $value in 
    ... 
    esac 
fi 

manual

此外,在执行case语句之前检查命令的返回码

pipefail

如果设置的返回值管道是最后一个 (最右边)命令以非零状态退出的值,如果全部为 管道中的命令成功退出。此选项已被 默认禁用。

+0

不适用于我,它仍然通过'情况0'。 **编辑**:你添加了代码,'$? == 0'逻辑应该工作。 – Jite

+0

@Jite看到编辑 – devnull

+0

我认为这是一个丑陋的解决方案,但。当* ssh失败时,'grep' /'wc' /'awk'命令将在本地执行,而不是在远程*执行,这就是为什么它不能按预期工作。我的解决方案应该更强大。 – Jite

0

这个怎么样(SSH命令后不应得到本地执行):

"$(ssh -n $host 'zfs list -t snapshot -o name -H | grep "tank/fs" | wc -l | awk \'{print $1}\')'" 

注意我怎么单引号的命令SSH远程机器上运行。对于awk,也逃脱',如\'。检查呼叫的返回值,并仅在返回成功时执行。

+1

无法解决问题,因为整个管道可能会失败,并且在未检查退出状态而不是提前短路时发生空白情况。 –

+0

@CharlesDuffy我在本地尝试了原始行。 ssh失败意味着管道命令在本地执行,'case 0'由于'wc -l'回显'0'而触发。在我的解决方案中,''''之间的所有内容都成为ssh的参数,'ssh'失败时'case 0'不会触发。但是,在进行字符串比较时恰好是这种情况。如果'ssh'打印了一个'0'行,它就会匹配'case 0'。只对'0'返回值做动作听起来像是一个好主意,我原本计划添加它,但由于某种原因取消了编辑:) – Jite