![如果无法以非交互方式建立 SSH 连接,请停止 bash 脚本](https://linux22.com/image/107934/%E5%A6%82%E6%9E%9C%E6%97%A0%E6%B3%95%E4%BB%A5%E9%9D%9E%E4%BA%A4%E4%BA%92%E6%96%B9%E5%BC%8F%E5%BB%BA%E7%AB%8B%20SSH%20%E8%BF%9E%E6%8E%A5%EF%BC%8C%E8%AF%B7%E5%81%9C%E6%AD%A2%20bash%20%E8%84%9A%E6%9C%AC.png)
我正在开发一个 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。您需要依赖其他东西来确定命令是否成功。