【问题标题】:How do I display the popen output as it happens through a get request?如何显示通过 get 请求发生的 popen 输出?
【发布时间】:2014-07-31 23:11:09
【问题描述】:

我有一些 Ruby 脚本用于自动执行一些可能需要很长时间才能完成的 rsync 任务。我正在使用popen 运行命令:

def process(command)
  io = IO.popen(command) 
  output = io.read
  io.close 
  return output 
end

该命令由 Sinatra 应用程序中的 get 请求执行:

get '/sync' do
  stream do |out|
    rsync_command = "rsync somedir" 
    out << process(rsync_command)
  end
end

然后我在前端使用 Ajax 请求访问输出:

$.get('/sync', function (data) {
 console.log(data);
});

是否可以在发生时显示 shell 输出,而不是只在进程结束时返回?

【问题讨论】:

    标签: javascript ruby shell unix sinatra


    【解决方案1】:

    IO::popen:

    将指定的命令作为子进程运行;子过程的标准 输入和输出将连接到返回的 IO 对象。

    stdout 是一个文件。您是在告诉 ruby​​ 使用 io.read 行读取整个文件,因此 ruby​​ 必须等到到达文件末尾才能返回文本,这发生在另一端关闭管道时,即目标程序完成时执行。您不必一次读取整个文件,而是可以逐行读取文件

    def process(command)
      IO.popen(command) do |io|
        io.each do |line|
          puts line
        end
      end
    end
    

    这告诉 ruby​​ 读取文件,直到找到换行符,然后返回文本...一遍又一遍,直到到达文件末尾。

    这是一个完整的例子:

    #my_prog.rb
    
    text = ""
    
    1.upto(10) do
      text << "."
    
      puts text
      STDOUT.flush
    
      sleep 1
    end
    

    ...

    def process(command)
      IO.popen(command) do |io|
        io.each do |line|
          puts line
        end
      end
    end
    
    my_command = 'ruby ./my_prog.rb'
    process(my_command)
    

    请注意,除非目标程序刷新输出,否则输出将被缓冲,因此在缓冲区填满之前无法读取文本(此时缓冲区将自动刷新)或目标程序结束(此时缓冲区也将自动刷新)。无需重复调用STDOUT.flush(),您只需使用程序顶部的STDOUT.sync = true 行即可。当 sync 设置为 true 时,ruby 不会缓冲输出。

    【讨论】:

    • 使用read 是一种非常糟糕的做法,因为它不可扩展。尝试读取文件中的所有内容可能会消耗所有可用空间并导致应用程序爬网。另一方面,逐行 I/O 速度极快且可无限扩展。
    • 与这篇文章中的任何内容或 SO 的任何其他帖子的相关性?
    • 相关性:OP 想做io.read。那是不可扩展的。你说使用io.each。那是可扩展的。这是 Stack Overflow 上经常重复的事情。这叫确认和同意你所说的,完全相关。
    【解决方案2】:
    IO.popen(command){ |f| puts f.lines.to_a }
    

    【讨论】:

    • 你真的试过了吗,例如与我的示例程序?你知道 lines() 已被弃用吗?你知道枚举器是如何工作的吗?当所有的行都没有被读取时,to_a() 怎么能返回?
    猜你喜欢
    • 2015-12-08
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    相关资源
    最近更新 更多