如果无法以非交互方式建立 SSH 连接,请停止 bash 脚本

如果无法以非交互方式建立 SSH 连接,请停止 bash 脚本

我正在开发一个 Bash 脚本,该脚本在脚本操作期间的给定点通过 git 建立 SSH 连接。我试图优雅地处理可能发生的一些错误,在脚本最终部分失败之前停止脚本。

在某一时刻,它会运行一条命令,类似于git push通过 SSH 发起推送的命令。这有可能是第一次连接到新主机,这会导致交互式提示,验证主机的有效性。

RSA key fingerprint is 96:a9:23:5c:cc:d1:0a:d4:70:22:93:e9:9e:1e:74:2f.
Are you sure you want to continue connecting (yes/no)? yes

我正在寻找有关如何避免 SSH 提示或在 SSH 主机之前尚未获得用户批准的情况下提前使脚本失败的想法。

我看了一下这个问题。可以说这个问题与那个问题重复,但那里列出的解决方案不适用于我的情况。我更愿意检测在没有提示的情况下无法建立 SSH 连接,并且在这种情况下会失败。

答案1

因此,您不想自动添加主机known_hosts,而是希望在主机尚不存在时使连接失败。StrictHostKeyChecking仍然可以选择执行此操作(如链接的问题中所示),但不要将其设置为no,而是将其设置为yes。如果主机密钥未知,这将导致连接失败。

$ ssh -oStrictHostKeyChecking=yes [email protected]
No ECDSA host key is known for somehost.somewhere and you have requested strict checking.
Host key verification failed.

ssh如果发生错误(包括这种情况),则会以状态 255 退出,因此您可以在脚本中使用类似的内容进行测试

if [ "$?" = 255 ] ; then
    echo "there was an error"
fi

当然,也可能是其他错误,您需要检查输出来ssh确定。

答案2

OpenSSH 客户端可以通过终端或 X11 显示屏提示用户。如果您想确保不会提示用户,请安排在没有控制终端和 X 显示的情况下运行客户端。摆脱 X 显示很容易:取消设置DISPLAY环境变量或将其设置为空字符串。要在没有控制终端的情况下运行该进程,请在单独的会话中运行它。没有 POSIX 实用程序可以做到这一点,但 Linux 有一个setsid公用事业。

DISPLAY= setsid ssh …

请注意,在其自己的会话中运行 SSH 客户端也会在其自己的进程组中运行它。使用的主要实际结果setsid是,如果从交互式 shell 执行脚本,Ctrl+C不会杀死 SSH 客户端;您应该在脚本中放置一个 SIGINT 陷阱来杀死 SSH 客户端。

ssh_pid=
trap INT TERM 'if [ -n "$ssh_pid" ]; then kill "$ssh_pid"; fi'
DISPLAY= setsid ssh … &
wait "$ssh_pid"
unset ssh_pid

请注意,ssh如果由于主机密钥验证失败而无法建立连接,则返回状态代码 0。您需要依赖其他东西来确定命令是否成功。

相关内容