【问题标题】:How do I get the STDOUT of a ruby system() call while it is being run?如何在运行时获取 ruby​​ system() 调用的 STDOUT?
【发布时间】:2011-05-17 09:23:53
【问题描述】:

类似于Getting output of system() calls in Ruby,我正在运行系统命令,但在这种情况下,我需要在命令运行时输出STDOUT。

【问题讨论】:

  • 奇怪的是你应该做一些特别的事情。根据我的经验,当我使用system 运行程序时,子程序的标准输出会转到父程序的标准输出,这似乎是您想要的。

标签: ruby


【解决方案1】:

在链接的问题中,答案再次是完全不使用system,因为system 不支持这一点。

不过这次的解决方案不是使用backticks,而是使用IO.popen,它返回一个IO 对象,您可以使用该对象在生成输入时读取它。

【讨论】:

  • 谢谢,我最终使用了IO.popen('command_to_run') { |io| while (line = io.gets) do puts line end }
【解决方案2】:

如果有人想阅读stdout stderr:
重要的是同时阅读它们,而不是第一个然后另一个。因为程序允许轮流甚至并行输出到stdoutstderr。所以,你需要线程。这个事实甚至不是 Ruby 特有的。

here窃取。

require 'open3'

cmd = './packer_mock.sh'
data = {:out => [], :err => []}

# see: http://stackoverflow.com/a/1162850/83386
Open3.popen3(cmd) do |stdin, stdout, stderr, thread|
  # read each stream from a new thread
  { :out => stdout, :err => stderr }.each do |key, stream|
    Thread.new do
      until (raw_line = stream.gets).nil? do
        parsed_line = Hash[:timestamp => Time.now, :line => "#{raw_line}"]
        # append new lines
        data[key].push parsed_line

        puts "#{key}: #{parsed_line}"
      end
    end
  end

  thread.join # don't exit until the external process is done
end

【讨论】:

    【解决方案3】:

    这是我的解决方案

    def io2stream(shell, &block)
      Open3.popen3(shell) do |_, stdout, stderr|
        while line = stdout.gets
          block.call(line)
        end
    
        while line = stderr.gets
          block.call(line)
        end
      end
    end
    
    io2stream("ls -la", &lambda { |str| puts str })
    

    【讨论】:

    • 这仅适用于某些程序。应该在两个并行线程中读取 stdout 和 stderr,因为程序可以并行写入这些输出。
    【解决方案4】:

    通过以下您可以捕获系统命令的标准输出:

    output = capture(:stdout) do
      system("pwd") # your system command goes here
    end
    
    puts output
    

    缩短版:

    output = capture(:stdout) { system("pwd") }
    

    同样,我们也可以使用:stderr 捕获标准错误

    capture方法由active_support/core_ext/kernel/reporting.rb

    提供

    查看该库的代码 cmets,capture 将被弃用,因此不确定当前支持的方法名称是什么。

    【讨论】:

      猜你喜欢
      • 2010-10-15
      • 1970-01-01
      • 2012-02-26
      • 2012-02-15
      • 1970-01-01
      • 2015-12-11
      • 2011-04-13
      • 2012-08-04
      • 1970-01-01
      相关资源
      最近更新 更多