【问题标题】:How can I read another program's STDOUT from a Ruby program line by line?如何从 Ruby 程序中逐行读取另一个程序的 STDOUT?
【发布时间】:2014-08-21 08:42:32
【问题描述】:

我有一个名为“count”的小型测试 Ruby 程序,计数为 1..50。

#!/usr/bin/ruby
#count
for i in 1..50 do
 STDOUT.puts i
 sleep 1
end

我想从另一个程序中调用它,并逐行读取输出的数字,然后从另一个程序中逐行输出。

但是我的构造不起作用:

IO.popen("count","r+") {|f| puts f.readline}

我应该怎么做才能让它工作?也许在测试程序“count”中进行了一些修改?

【问题讨论】:

    标签: ruby io stdout stdin popen


    【解决方案1】:

    如果你有一些耐心(大约 50s),你会看到你确实得到了一行输出,那一行将是 "1\n"。你有两个问题:

    1. count 正在使用缓冲输出。这意味着在count 的输出缓冲区已满之前,您的stdin 中不会显示任何内容;鉴于您要打印的字节数很少,在count 完成之前不会刷新缓冲区。
    2. 您的popen 块仅在寻找一行。

    您可以通过使用STDOUT.sync = true关闭count中的输出缓冲来解决第一个问题:

    STDOUT.sync = true
    for i in 1..50 do
      STDOUT.puts i
      sleep 1
    end
    

    然后在您的popen 中,您可以使用each 遍历这些行:

    IO.popen("count","r+") { |fp| fp.each { |line| puts line } }
    

    那么你应该每秒显示一行输出。

    【讨论】:

    • 如果我的测试程序是一个普通程序怎么办?例如 cURL 或 WGET,在这种情况下如何设置 STDOUT.sync=true?还是我应该编写一个调用普通程序的“包装”Ruby 程序?
    • 你试过curlwget吗?期望在管道中使用的程序往往是管道感知的,并且自己做正确的事情。否则,您将等到缓冲区填满。
    猜你喜欢
    • 2011-06-20
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多