我想使用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'
效果很好。
答案 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)