在脚本内处理“权限被拒绝”

在脚本内处理“权限被拒绝”

我制作了一个脚本,其中一个函数通过 ssh 从远程服务器接收信息:

session_check() {
    ssh -o BatchMode=yes $USER@$SERVER my_command | grep "value" > /dev/null
}

按照计划,访问将使用密钥,但如果密钥未加载到远程计算机上,我会得到:

Permission denied (publickey,password)

我不能使用返回0或1,因为如果访问服务器成功,但命令不成功,也会以相同的方式返回1。我需要以某种方式隐藏“权限被拒绝”消息,并设置一个只有在收到此类消息时才会满足的条件。

我希望我写清楚了。提前致谢!

更新 我弄清楚了如何使用 stderr ( 2>> (grep "value")),但我仍然无法将它与上面的函数一起使用。所以我需要将 stderr 重定向到某个地方以供以后使用。但为了以某种方式从服务器上执行命令中获得 ruselt(如果可以连接到服务器)。我怀疑这通常是不可能用一个命令来实现的,我需要先检查连接是否成功,然后再执行该命令。你怎么认为?

答案1

在您的脚本中,因为您使用的是管道,所以您已经忽略了my_command;的退出状态。管道的退出状态将是管道中最后一个命令的退出状态。

不过,Bash 允许您检查管道中任何命令的退出代码;现在您只需确保您的远程命令始终成功。因为您已经忽略了它的退出状态,所以我们不会引入任何新的错误。

session_check() {
    ssh -o BatchMode=yes $USER@$SERVER 'my_command; exit 0' | grep -q "value"
    local rc=$?
    if [[ ${PIPESTATUS[0]} != 0 ]]; then
        return 127
    fi
    return $rc
}

如果你也想获得退出状态my_command,那将会变得更加困难;也许然后将其分成两个单独的命令。

session_check() {
    status=$(ssh -o BatchMode=yes $USER@$SERVER 'my_command; echo $?') &&
    sed '$d' <<<"$status" | grep -q "value"
    return $(sed -n '$p' <<<"$status")
}

请注意我们如何将退出代码作为ssh命令的最后一行文本输出偷偷取出,然后重复遍历它。为了提高效率,这可能应该被重构,但至少展示了一种在需要时实现它的方法。

请注意,我们在这里使用了几个仅 Bash 的功能;脚本需要有#!/bin/bash,而不是#!/bin/sh在 shebang 中。

对这种欺骗的需要表明,在 shell 处理模型中的受控错误处理方面,您已接近可行的边界。也许您想尝试用 Python 等现代脚本语言重写部分或全部内容。

相关内容