Is there an Expect equivalent gem for Ruby?

前端 未结 6 620
一生所求
一生所求 2020-12-05 14:16

Is there an Expect equivalent gem for Ruby?

I tried searching on code.google and rubygems.org, but sadly it did not show up.

FYI: Expect is a Unix automation

相关标签:
6条回答
  • 2020-12-05 14:50

    checkout this rubygem: https://github.com/abates/ruby_expect. It could handle some small task for you. from its official example, it's enough to 'enter password' and login and interactive with local script.

    here is an example that update the git code (which is authenticated with password):

    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
    

    just run the code above, and your will see like this:

    $ 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.
    

    for more example and details, please dive into its source code.

    0 讨论(0)
  • 2020-12-05 14:51

    I recently spent quite a bit of time struggling with this issue (I am stuck with 1.8.7). I found this question, this blog post and this forum thread really useful.

    At the end this is my application code if anyone is interested in a little example (pass the password to rpm when signing packages):

    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 
    

    It has little error checking but it was all I needed.

    Edit: Update the code with Process.wait(pid) to make sure it finishes before continuing and add comment about this being for 1.8.7.

    0 讨论(0)
  • 2020-12-05 14:53

    RExpect

    From the project's website:

    RExpect is a drop in replacement for the expect.rb module in the standard library that is faster and more robust, cabable of driving many devices simultaneously.

    0 讨论(0)
  • 2020-12-05 14:53

    parley is another one you can try, (written by me). It is inspired by Perl expect.

    0 讨论(0)
  • 2020-12-05 15:05

    Ruby comes with the PTY module for setting up pseudoterminals to drive interactive command line applications. With it comes an expect method that allows you to interact with an application kinda like Expect. For learning how to use expect, I found "What to expect from the Ruby expect library?" helpful.

    As far as gems go, maybe checkout greenletters which is supposed to improve upon PTY + expect (although I haven't tried it myself).

    0 讨论(0)
  • 2020-12-05 15:06

    expect4r seems to do what you are asking for, though it is made specific for connections to Cisco and Juniper devices.

    Perhaps even better is yax as this is "yet another expect".

    0 讨论(0)
提交回复
热议问题