Running a command from Ruby displaying and capturing the output

前端 未结 4 1716
情书的邮戳
情书的邮戳 2020-12-01 03:33

Is there some way to run a (shell) command from Ruby displaying but also capturing the output? Maybe with the help of some gem?

What I mean by displaying is not prin

相关标签:
4条回答
  • 2020-12-01 03:55

    You can redirect the output

    system 'uptime > results.log'
    

    or save the results.

    result = `uptime`
    result = %x[uptime]
    

    see here. Getting progress information or output in realtime is more complicated, I doubt that there is a simple solution. Maybe it is possible with advanced process management functions such as Open3.popen3. You could also try to use a pseudo terminal with pty and grap the output there.

    0 讨论(0)
  • 2020-12-01 04:03

    I used open3 to captured the output of executed shell command from ruby code.

    require 'open3'
    
    stdout, stdeerr, status = Open3.capture3("ls")
    
    puts stdout
    
    0 讨论(0)
  • 2020-12-01 04:08

    If you are willing to explore a solution outside the standard library, you may also use Mixlib::ShellOut to both stream output and capture it:

    require 'mixlib/shellout'
    cmd = 'while true; do date; sleep 2; done'
    so = Mixlib::ShellOut.new(cmd)
    so.live_stream = $stdout
    so.run_command
    out = so.stdout
    
    0 讨论(0)
  • 2020-12-01 04:13

    You can run system call like this:

    `sleep --help`
    

    Or like this

    system "sleep --help"
    

    Or

    %x{ sleep --help }
    

    In case of system it will print output and return true or nil, other two methods will return output

    PS Oh. It is about displaying in real time.

    So. You could use something like this:

    system("ruby", "-e 100.times{|i| p i; sleep 1}", out: $stdout, err: :out)
    

    To print data in realtime and store it in variable:

    output = []
    r, io = IO.pipe
    fork do
      system("ruby", "-e 3.times{|i| p i; sleep 1}", out: io, err: :out)
    end
    io.close
    r.each_line{|l| puts l; output << l.chomp}
    #=> 0
    #=> 1
    #=> 2
    p output
    #=> ['0', '1', '2']
    

    Or use popen

    output = []
    IO.popen("ruby -e '3.times{|i| p i; sleep 1}'").each do |line|
      p line.chomp
      output << line.chomp
    end
    #=> '0'
    #=> '1'
    #=> '2'
    p output
    #=> ['0', '1', '2']
    
    0 讨论(0)
提交回复
热议问题