【问题标题】:Is there an Expect equivalent gem for Ruby?Ruby 是否有 Expect 等效的 gem?
【发布时间】:2011-10-31 20:39:56
【问题描述】:

是否有与 Ruby 等效的 Expect 宝石?

我尝试在 code.google 和 ruby​​gems.org 上搜索,但遗憾的是没有显示出来。

仅供参考:Expect 是一个 Unix 自动化和测试工具,由 Don Libes 作为 Tcl 脚本语言的扩展编写,用于 telnet、ftp、passwd、fsck、rlogin、tip、ssh 等交互式应用程序.

【问题讨论】:

  • @jokester 你的意思是this
  • @mu 太短:感谢对 Expect 的额外介绍。当然,我的帖子似乎还不够。
  • 你读过this thread吗?

标签: ruby expect


【解决方案1】:

Ruby 带有PTY 模块,用于设置伪终端来驱动交互式命令行应用程序。随之而来的是expect method,它允许您与有点像 Expect 的应用程序进行交互。对于学习如何使用 expect,我发现“What to expect from the Ruby expect library?”很有帮助。

就 gems 而言,也许结帐 greenletters 应该比 PTY + expect 有所改进(尽管我自己还没有尝试过)。

【讨论】:

  • 链接现在好像坏了。
【解决方案2】:

我最近花了很多时间来解决这个问题(我坚持使用 1.8.7)。我发现这个question、这个blog post 和这个forum thread 真的很有用。

如果有人对一个小例子感兴趣的话,最后这是我的应用程序代码(在签名包时将密码传递给 rpm):

def run_interactive command, password, promt
  output   = ''
  begin
    r, w, pid = PTY.spawn(command)
    puts r.expect(promt)
    sleep(0.5)
    w.puts(password)
    begin
      r.each { |l| output += l } 
    rescue Errno::EIO
    end
    $?.exitstatus
    Process.wait(pid)
  rescue PTY::ChildExited => e
    $stderr.puts "The child process #{e} exited! #{$!.status.exitstatus}"
  end 
  output
end

password = "mypassword"
command  = "rpm --define '_signature gpg' --define '_gpg_name #{key_id}' --addsign #{package}"
promt    = %r{.*: }
expected = %r{good}
output = run_interactive(command, password, promt)
if output.match(expected)
  puts output
else
  abort "Error: expected: '#{expected}' got '#{output}'"
end 

它几乎没有错误检查,但这就是我所需要的。

编辑:使用Process.wait(pid) 更新代码以确保它在继续之前完成,并添加关于1.8.7 的评论。

【讨论】:

  • 另外需要注意的是,pty gem 在 1.8.7 上在某些平台(HP UX 和 solaris 等)上被破坏了。您会看到类似于open: pty slave: Is a directory 的神秘错误。我还没有深入到代码中,看看是否可以找到解决方法;在某一时刻,它试图打开一个设备并使用路径 /dev 而不是完整的设备路径调用 open
【解决方案3】:

查看此 ruby​​gem:https://github.com/abates/ruby_expect。它可以为您处理一些小任务。从其官方示例来看,“输入密码”并登录并与本地脚本交互就足够了。

这是一个更新 git 代码的示例(使用密码进行身份验证):

require 'rubygems'
require 'ruby_expect'

def update_code
  password = 'your password here'
  exp = RubyExpect::Expect.spawn('git pull', :debug => true)
  exp.procedure do
    each do
        expect /password: / do
            send password
        end
    end
  end
end

update_code

只要运行上面的代码,你会看到这样的:

$ ruby update_code.rb 

shensiwei@gforge.1ver??.net's password: 
remote: Counting objects: 133, done.
remote: Compressing objects: 100% (84/84), done.
remote: Total 85 (delta 62), reused 0 (delta 0)
Unpacking objects: 100% (85/85), done.

有关更多示例和详细信息,请深入了解其源代码。

【讨论】:

    【解决方案4】:

    expect4r 似乎可以满足您的要求,尽管它专门用于连接到 Cisco 和 Juniper 设备。

    yax 可能更好,因为这是“又一个期望”。

    【讨论】:

      【解决方案5】:

      RExpect

      来自项目的网站:

      RExpect 是在 更快、更健壮、可驱动的标准库 许多设备同时进行。

      【讨论】:

        【解决方案6】:

        parley 是另一个你可以试试的,(我写的)。它的灵感来自 Perl expect。

        【讨论】:

          猜你喜欢
          • 2015-10-13
          • 1970-01-01
          • 1970-01-01
          • 2011-02-18
          • 2014-08-18
          • 1970-01-01
          • 2011-04-14
          • 1970-01-01
          • 2010-09-29
          相关资源
          最近更新 更多