15

我想用来通过 sshexpect运行一个简单的命令。cat /tmp/id_rsa.pub

在 shell 中,我可以运行这个问题,(手动输入密码)

ssh root@localhost 'cat /tmp/id_rsa.pub'

我想用expect. 我的expect剧本是

#!/usr/bin/expect
eval spawn ssh root@localhost 'cat /tmp/id_rsa.pub'
expect "password:"
send "123456"
expect eof

它抛出错误bash: cat /tmp/id_rsa.pub: no such file or directory。我觉得很奇怪。可能的原因是什么?

编辑:经过一些测试,我发现这很常见,不仅在cat. 如果 spawned 命令的参数带有空格(即使它在引号中),它也会有问题。例如,用cat /tmp/id_rsa.pub空格替换其他命令,如

eval spawn ssh root@localhost 'which java'

它抱怨bash: which java: command not found。但是,如果将其替换为pwd,例如

eval spawn ssh root@localhost 'pwd'

它工作正常。

4

3 回答 3

8

与 sh 和其他兼容的 shell 不同,单引号 ( ') 对 Expect 没有特殊含义。
这意味着你的陈述

spawn ssh root@localhost 'cat /tmp/id_rsa.pub'

被解析成以下单词:

  • spawn
  • ssh
  • root@localhost
  • 'cat- 直到另一个单引号。
  • /tmp/id_rsa.pub'

sh 中的用法是将其分组为单个参数。在 Tcl 中,您可以使用双引号 ( ") 或大括号 ( {})。在双引号内,Tcl 变量将被替换,而里面的内容{}被传递而没有任何替换1

tl;dr sh 的 Expect/Tcl 等价物'{}.

换行前的1 A\仍将被替换。

于 2013-10-16T12:02:44.067 回答
5

正如约翰内斯所说,使用'是行不通的。
我遇到了类似的问题,但我想执行更多命令,然后仍然获得登录 shell。我设法使它与"

expect -c "
   set timeout 5;
   spawn ssh -XY $user@$host -t \"cat /etc/motd; bash -l\"
   expect {
      -re \"^Warning.*\" {exp_continue}
      -re \"^.*sword: \" {send \"${PASSWORDS[$user]}\r\"; interact}
   }
"
于 2014-03-05T10:33:19.857 回答
0

我想你不需要eval那里。删除它并检查。

检查此期望示例链接以获取有关“如何使用expect?”的详细示例 .

希望这可以帮助。

于 2012-09-20T18:14:55.757 回答