在shell脚本中使用expect

我需要传递两个参数,第一个是要执行的命令,第二个是密码。

这是我的expect.sh

 #!的/ usr / bin中/预期
 spawn [lrange $ argv 0 0]
期待“密码:”
发送[lindex $ argv 1]
相互作用

主要脚本:

 ./expect.sh“ssh root @ $ SERVER1”$ SERVER1_PASS

错误:

无法执行“{ssh root@xxx.xxx.xx.xxx}”:没有这样的文件或目录
    在执行时
 “spawn [lrange $ argv 0 0]”
     (文件“./expect.sh”第2行)

为什么?

据我所知,派生的第一个参数需要是一个字符串,而不是一个字符串列表。

并试图将一个多字命令行作为单个字符串将会导致问题。 我认为在调用产卵之前你必须分割空间,如果一个参数包含一个空格,那将会中断。 也许最好将密码指定为第一个参数,将命令指定为参数的其余部分。

所以试试像这样:

#!/usr/bin/expect spawn [lindex $argv 1] [lrange $argv 2 end] expect "password:" send [lindex $argv 0] interact 

但是即使这样也行不通。

根据Re:expect – spawn在comp.lang.tcl( Google Groups版本 )上的参数列表失败 ,我们必须调用eval来拆分列表。

所以答案应该是:

 #!/usr/bin/expect eval spawn [lrange $argv 1 end] expect "password:" send [lindex $argv 0] interact 

最后,你需要在密码后发送回车,所以你想要:

 #!/usr/bin/expect eval spawn [lrange $argv 1 end] expect "password:" send [lindex $argv 0] send '\r' interact 

然后切换顺序,调用时不要引用该命令:

 ./expect.sh "$SERVER1_PASS" ssh root@$SERVER1 

但其他人已经这样做了。 我们不需要重新发明轮子。

请参阅例如expect ssh登录脚本

就scp而言,我发现shell脚本非常令人不安。 我决定在crontab中使用php脚本。

PHP有一个功能

 $conn = ssh2_connect($scpserver, 22); 

然后打电话

 ssh2_auth_password($conn, $scpUser, $scpPassword); ssh2_scp_send($conn, $scpLocalPath, $scpRemotePath); 

要么

 ssh2_scp_recv($conn, $scpRemotePath, $scpLocalPath); 

你完成了。

当然,你需要定义用户,密码和其他的变量

虽然我建议你创建一个Linux用户只是为了这个目的的SCP。

为了安装ssh2,请尝试