如何按组分隔远程 ssh 退出代码?

How to separate remote ssh exit codes by groups?

我正在执行远程 SSH 请求,例如 ssh root@server "cat somefile".

如何判断失败是因为command/file问题(例如文件不存在、命令错误、参数错误等)还是连接问题(例如SSH端口关闭、主机宕机) , DNS 未解析等)?

我知道我可以使用特定的退出代码,但是有没有一些通用的方法可以不指定每个退出代码? 像

if [ $? -eq 1 ]; then
    echo "command error"
elif [ $? -eq 2 ]; then
    echo "connection error"
fi

来自man ssh

ssh exits with the exit status of the remote command or with 255 if an error occurred.

所以只有一个特殊的退出代码。您不必为 "SSH port is closed""the host is down" 等保留退出代码列表.

如果您的命令永远不会以 255 退出,或者您不关心您可以使用的特定代码

ssh root@server 'some command'
sshstatus=$?
if (( status == 255 )); then
    echo "connection error"
elif (( status != 0 )); then
    echo "command error"
fi

如果您需要从命令中捕获所有退出代码(甚至 255),或者您真的、真的、真的不想手动指定任何特殊的退出代码,那么您必须打印命令的退出代码在服务器端并在客户端提取它:

cmdstatusfile=$(mktemp)
ssh root@server 'some command; status=$?; wait; printf %3d $status' |
    tee >(tail -c3 "$cmdstatusfile") | head -c-3
sshstatus=$?
cmdstatus=$(< "$cmdstatusfile")
rm "$cmdstatusfile"
if (( sshstatus != 0 )); then
    echo "connection error"
elif (( cmdstatus != 0 )); then
    echo "command error"
fi

如果您通常将 ssh ... 传送到某些内容中,您仍然可以这样做。只需在 head ....

之后添加您的管道

这种方法假定 some command 总是正常退出。如果 set -eexitsome command 中,退出代码不会在最后打印出来。在这些情况下,您可以在陷阱中打印退出代码。