Running a shell command from Ruby: capturing the output while displaying the output?

后端 未结 7 1435

I have a problem.

I want to run a ruby script from another ruby script and capture it\'s output information while letting it output to the screen too.

runner

相关标签:
7条回答
  • 2021-02-10 02:51

    Have your script do its prompt output to stderr.

    echo "Enter something" >&2
    read answer
    echo "output that will be captured"
    

    This will be done for you if you use read -p to issue the prompt:

    read -p "Enter something" answer
    echo "output that will be captured"
    
    0 讨论(0)
  • 2021-02-10 02:54

    Try this:

    rd, wr = IO::pipe
    pid = Process.fork do  
      $stdout.reopen(wr)
      rd.close
      exec("command")
    end
    wr.close
    rd.each do |line|  
      puts "line from command: #{line}"
    end
    Process.wait(pid)
    

    Similar if you want to capture stderr. If you need to capture both it would a bit more difficult (Kernel.select?)

    Edit: Some explanation. This is an ancient Unix procedure: pipe + fork + calls to dup2 (reopen) depending on what you want. In a nutshell: you create a pipe as a means of communication between child and parent. After the fork, each peer close the pipe's endpoint it does not use, the child remaps (reopen) the channel you need to the write endpoint of the pipe and finally the parent reads on the read channel of the pipe.

    0 讨论(0)
  • 2021-02-10 02:55

    runner.rb

    STDOUT.print "Enter your password: "
    password = gets.chomp
    puts "Here is your password: #{password}"
    

    Note STDOUT.print

    start.rb

    require "stringio"
    
    buffer = StringIO.new
    $stdout = buffer
    
    require "runner"
    
    $stdout = STDOUT
    buffer.rewind
    
    puts buffer.read.match(/Here is your (password: .*)/).captures[0].to_s
    

    output

    Enter your password: hello
    password: hello
    

    Read more...

    I recently did a write-up on this here: Output Buffering with Ruby

    0 讨论(0)
  • 2021-02-10 03:06

    You could use tee to write the contents to a file or a pipe, and read the file afterwards.

    0 讨论(0)
  • 2021-02-10 03:08

    Have a look at POpen4. It claims to be platform independent (but I do not think it works in jruby where you can use IO#popen instead).

    0 讨论(0)
  • 2021-02-10 03:09

    For script independent output logging you might want to enable it from the terminal emulator (shell container). screen -L OR xterm -l This will capture all output produced by any shell or program running inside the emulator, including output generated by your ruby scripts.

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