繁体   English   中英

如何显示通过get请求发生的popen输出?

[英]How do I display the popen output as it happens through a get request?

我有一些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输出,而不是仅在过程结束时返回它?

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不会缓冲输出。

IO.popen(command){ |f| puts f.lines.to_a }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM