与Getting output of system() calls in Ruby类似,我正在运行系统命令,但在这种情况下,我需要在命令运行时输出STDOUT。
答案 0 :(得分:13)
与链接问题一样,答案是根本不再使用system
,因为system
不支持此功能。
但是这次解决方案不是使用backticks
,而是使用IO.popen
,它返回一个IO对象,可以在生成时读取输入。
答案 1 :(得分:0)
这是我的解决方案
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 })
答案 2 :(得分:0)
如果有人可能想阅读stdout
和 stderr
:
重要并行阅读它们,而不是先阅读另一个。因为程序可以轮流甚至并行输出到stdout
和stderr
。因此,您需要线程。这个事实甚至不是特定于 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