【问题标题】:Running a command from Ruby displaying and capturing the output从 Ruby 运行命令,显示和捕获输出
【发布时间】:2012-04-19 08:39:29
【问题描述】:

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

我所说的显示不是在最后打印它,而是当它出现时,用户可以在运行慢命令时得到反馈。

【问题讨论】:

    标签: ruby


    【解决方案1】:

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

    `sleep --help`
    

    或者像这样

    system "sleep --help"
    

    或者

    %x{ sleep --help }
    

    如果是system,它将打印输出并返回truenil,其他两种方法将返回输出

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

    【讨论】:

    • 我知道那些运行命令的方法,它们都没有将输出捕获到字符串中并同时输出。
    • 我没有看到任何带有outerr 参数的system 变体?这是 Ruby 2.0 吗?
    • @Matthias for old ruby​​ you need => ("hash rocket") 符号,所以: , out: io, err: :out 变成 , :out => io, :err => :out
    • system("ruby", "-e 3.times{|i| p i; sleep 1}", :out => io, :err => :out) NOT WORKING: in `system ': 无法将 Hash 转换为 String (TypeError)
    • system with out: and err:, nice!
    【解决方案2】:

    你可以重定向输出

    system 'uptime > results.log'
    

    或保存结果。

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

    here。获取进度信息或output in realtime 比较复杂,我怀疑是否有简单的解决方案。也许可以使用高级process management functions,例如Open3.popen3。您也可以尝试使用pseudo terminal with ptygrap the output there

    【讨论】:

    • 谢谢。帮助过我。只需添加以下行 puts result 。这将在控制台中显示结果。
    【解决方案3】:

    我使用open3 从 ruby​​ 代码中捕获了执行的 shell 命令的输出。

    require 'open3'
    
    stdout, stdeerr, status = Open3.capture3("ls")
    
    puts stdout
    

    【讨论】:

    • 这应该是公认的答案!它为您提供“结果”,然后您可以使用它,它是标准库的一部分。
    • +80 应该这样做:)
    【解决方案4】:

    如果您愿意探索标准库之外的解决方案,您也可以使用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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-01
      • 1970-01-01
      • 2012-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-04
      相关资源
      最近更新 更多