48

是否有某种方法可以从 Ruby 显示运行(shell)命令,但也可以捕获输出?也许在一些宝石的帮助下?

我所说的显示不是在最后打印它,而是当它出现时,用户会在运行慢命令时获得正在发生的事情的反馈。

4

4 回答 4

79

您可以像这样运行系统调用:

`sleep --help`

或者像这样

system "sleep --help"

或者

%x{ sleep --help }

如果system它会打印输出并返回trueor nil,其他两种方法将返回输出

PS哦。它是关于实时显示的。

所以。你可以使用这样的东西:

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

要实时打印数据并将其存储在变量中:

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']

或使用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']
于 2012-04-19T08:49:21.697 回答
15

您可以重定向输出

system 'uptime > results.log'

或保存结果。

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

这里实时获取进度信息或输出比较复杂,我怀疑是否有简单的解决方案。也许可以使用诸如Open3.popen3 之类的高级进程管理功能。您还可以尝试使用带有 pty 的伪终端在那里获取输出

于 2012-04-19T08:51:59.013 回答
14

我曾经open3从 ruby​​ 代码中捕获执行的 shell 命令的输出。

require 'open3'

stdout, stdeerr, status = Open3.capture3("ls")

puts stdout
于 2016-03-22T09:08:02.577 回答
0

如果您愿意探索标准库之外的解决方案,您也可以使用Mixlib::ShellOut流输出和捕获它:

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
于 2018-04-10T18:12:22.163 回答