使用expect生成带有包含空格的参数的命令

时间:2012-09-20 18:08:05

标签: bash automation automated-tests expect

我想使用expect在ssh上运行一个简单的命令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。如果生成命令的参数是带空格的(即使它在引号中),它也会有问题。例如,将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'

效果很好。

3 个答案:

答案 0 :(得分:3)

单引号(')对于Expect没有特殊含义,与sh和其他兼容的shell不同 这意味着您的声明

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 换行前的\仍将被替换。

答案 1 :(得分:3)

正如约翰内斯所说,使用'不起作用 我有类似的问题,但我想执行更多的命令,然后仍然得到一个登录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}
   }
"

答案 2 :(得分:0)

我猜你不需要eval。删除它并检查。

有关“如何使用expect”的详细示例,请查看此expect examples link

希望这有帮助。