当从Ruby调用时,期望脚本冻结

时间:2010-12-20 10:11:42

标签: ruby unix expect

我有一个我需要安装公钥的主机列表。为此,我编写了一个调用expect脚本的ruby脚本,并将密码,主机名和公钥文件传递给它。这个期望脚本依次通过输入密码并对未知主机密钥回答“是”来对每个主机执行ssh-copy-id。

运行命令行时,expect脚本运行正常。但是当从ruby脚本执行时,对于未知的主机密钥确认,期望无法回答“是”:“您确定要继续连接(是/否)?”。当抛出是/否问题时,期望脚本会冻结。

非常感谢任何帮助。

这是我的红宝石脚本:

#!/usr/bin/env ruby -w

hosts=['test@blah1.edu','test2@blah2.edu','test3@blah3.edu']
password="blahblahblah"
key_file="/home/blah/.ssh/id_rsa.pub"

hosts.each{ |host|
   command="expect sshcopy.exp #{host} #{key_file} #{password}"
  `#{command}`
}

这是我的期望脚本 sshcopy.exp

set host [lrange $argv 0 0]
set key_file [lrange $argv 1 1]
set password [lrange $argv 2 2]
spawn  ssh-copy-id -i $key_file $host
expect -nocase "*password: $" {send "$password\r"; interact}  -nocase "*are you sure you want to continue connecting (yes/no)? $" {send "yes\r"}  eof{exit}
expect -nocase "*password: $" {send "$password\r"; interact} eof{exit}

您将在上面看到两个期望陈述。第一个语句处理立即通过交互立即询问密码(即主机密钥已知)的情况。它还通过回答“是”来处理识别未知主机的情况。

第二个期望语句在第一个期望回答“是”时执行,导致密码被询问。

2 个答案:

答案 0 :(得分:1)

我想问题是您使用`backticks`调用expect脚本,但是期望脚本会进行交互。似乎ruby反引号不允许完全交互(也许阻止stdin)。您可能想要调查ruby的expect模块并取消单独的expect脚本。

答案 1 :(得分:0)

谢谢你们。但我发现问题的答案很简单:

  puts `#{command}`

我认为``在ruby中会将shell命令的stdout和stderr句柄与ruby脚本合并。这是错误的。