我有一个正在运行的系统,它使用 scp(1) 将文件从一台主机复制到另一台主机。系统正在处理一系列文件,但卡在其中一个文件上:也就是说,它昨天启动了一个 scp 命令,该命令今天仍在运行。
运行 strace 表明 scp 正在等待读取管道文件,该文件连接到其 ssh 子进程的 stdout;这个孩子正在等待阅读 fd 4,即/dev/tty
。
known_hosts
一个 ssh 目标的主机密钥与源主机上的冲突。我在长期运行的 SCP 启动时摆弄了它;现在known_hosts
一切都已设置完毕,我可以从源 ssh 到所有目的地,而不会出现任何提示。
我的假设是,ssh
遇到了一个小的计时窗口,并向用户提供了未知的主机密钥,并且正在等待确认 ( "yes\n"
) 继续。
有什么方法可以让read
调用的ssh
行为就像用户键入一样yes
(如果是这样,如何)?
当(在另一台机器上)我echo foobar > /dev/tty
在 xterm 中时,它会foobar
在我的控制台上写入。毫不奇怪,如果 Iecho foobar > /proc/<pid>/fd/4
是 的符号链接,则会发生相同的结果/dev/tty
。那么如何将输入输入到 ssh 中呢?
如果有人知道如何检验我的假设ssh
和/或使其以不同的方式进行,我也很高兴听到这一点。
答案1
写入时/dev/tty
不考虑进程 ID;这样你就不会成功。
虽然是一样的设备,进程将在给定设备上打开不同的文件描述符。对于 Linux,如果您知道进程 ID,即 /proc/,则可以操作单独的文件描述符PID/fd/0 是 id 为的进程的标准输入PID。
对于您的情况,程序正在打开设备,其文件描述符也将位于 /proc/ 中PID/fd(但不太清楚)。应用程序可以“查看”该目录中的符号链接信息,并对其进行操作。
如果你仔细观察,/proc/ 中的项目PID/fd 都有不同的 inode 值(因为它们是不同的文件描述符)。回显 proc/ 中的条目PID/fd 表示您正在回显该文件描述符。
但是 ssh 并不期望来自该方向的输入,也没有提供补充提示 - 您正在使用的解决方法可能是您能做的最好的解决方法。
答案2
在使用经常重新安装的嵌入式系统(从而生成新的主机密钥)时,我避免了这个问题。如果你想盲目接受新的主机密钥,你可以这样做,但要注意,这消除对冒充对方的任何防御。它可能适合在控制良好的网络上进行低风险操作,但不建议在公共互联网上使用!
对于有问题的主机,使 ssh write 自动接受新的主机密钥,但将其写入/dev/null
:
Host h
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
SSH 似乎没有从不检查的选项known_hosts
。
如果问题中的问题是该客户端从未知道主机密钥(而不是已知但现在已更改),那么添加-o StrictHostKeyChecking=no
到 SSH 命令行就足够了。
重申一下,仅当您接受安全性降低时才执行此操作。我假设您这样做,正如您所说,您希望无条件响应yes
交互式 SSH。