运行 通过 expect 的 SSH,在到达提示后发送的第一个字符处冻结

Running SSH through expect, freezes at first character sent after prompt is reached

我正在编写一个 expect 脚本来针对特定类型的 IoT 设备自动执行诊断 SSH 会话。该脚本 运行 来自跳转主机,其中使用该脚本的用户 运行 需要提升权限才能访问用于 SSH 身份验证的密钥文件。

身份验证有效,我到达了 IoT 设备的 shell 提示符,但是当我向提示符发送命令时(下面脚本中的 ls -l),输出冻结并且没有其他任何反应。

期待脚本 rundiag.expect:

#!/usr/bin/expect
set timeout 30

set ip [lindex $argv 0]
set port [lindex $argv 1]
set passphrase [lindex $argv 2]
set ssh_key_file [lindex $argv 3]

spawn /usr/bin/sudo -u sftp /usr/bin/ssh -ldiag_user -i $ssh_key_file $ip -p $port -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no"
expect "passphrase for"
send "$passphrase\r"
expect "DEBUG> "
send "ls -l\r"
expect "DEBUG> "

运行ning脚本时的输出:

$ expect rundiag.expect 10.10.10.123 22 somePassword /opt/the_keyfile
spawn /usr/bin/sudo -u sftp /usr/bin/ssh -ldiag_user -i /opt/the_keyfile 10.10.10.123 -p 22 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
Warning: Permanently added '10.10.10.123:22' (RSA) to the list of known hosts.
Enter passphrase for key '/opt/the_keyfile':
******

Welcome to diagnostics shell

DEBUG> l

最后回显的lls -l命令的第一个字符,但随后输出就停止了,直到脚本超时。

我尝试了一些天真的方法,例如通过 send_tty 发送或使用 \n 而不是 \r 结束命令,但无济于事。

到达 shell 提示符后,我应该更改什么才能执行 运行 命令?

事实证明,这些 IoT 设备上的 SSH 实现存在相当严重的缺陷,因为由于遗留原因,它反过来封装了一个内部 Telnet 服务器。

在连接后添加 0.5 秒的睡眠(当设备通过 Telnet 在另一个端口上连接到自身时)和在输入命令和发送之间添加 0.1 秒的睡眠 \r 达到了目的。