使 Net:SSH 更新在执行块中更频繁地更新返回的数据包/块



我在远程服务器上有一个 ruby 脚本,我在本地 PC 上通过 Net:SSH 运行。

远程脚本需要几分钟才能运行,并将其进度输出到 stdout。

我遇到的问题是我的exec命令中的块仅在数据包/块已满时才被调用。
所以我大约每分钟都能一击就能得到所有进度。

以下是一些精简示例来说明我的问题:

服务器脚本:

(0.999).each do |i|
  puts i
  sleep 1
end
puts 1000

本地脚本:

Net::SSH.start('ip.v.4.addr', 'user', :keys => ['my_key']) do |ssh|
  ssh.exec("ruby count_to_1000.rb") do |ch, stream, data|
    puts data if stream == :stdout
  end
  ssh.loop(1)
end

远程脚本有什么方法可以强制发送数据包/块吗?
或者有没有办法在刷新之前设置一秒(或 n 位)的限制?(内网:SSH)

感谢您的帮助!

尝试flush

http://www.ruby-doc.org/core-2.1.5/IO.html#method-i-flush

(0.999).each do |i|
  puts i
  STDOUT.flush
  sleep 1
end

sync

http://www.ruby-doc.org/core-2.1.5/IO.html#method-i-sync

STDOUT.sync = true
(0.999).each do |i|
  puts i
  sleep 1
end

(未经测试,顺便说一句。也许它们需要在客户端或其他 IO 流上使用。但这是立即想到的两种方法。

在我的测试设置中,这按预期工作(使用本地主机测试)。但是,标准输出刷新可能存在一些问题。

您可以尝试写信给STDOUT而不是使用puts(我听说有一些我不太了解的区别)。

因此,您可以在服务器上使用:

(0.999).each do |i|
  STDOUT.puts i
  sleep 1
end
STDOUT.puts 1000
#You could possibly also use "STDOUT.write 1000", but it will not append a newline, like puts does.

如果这不起作用,则可以尝试使用 STDOUT.flush() 强制刷新STDOUT。我相信通过向 STDOUT 写入空字符串可以实现相同的效果,但我不是 1000% 确定。

由于某种原因,exec命令实际上也可能会等待整个过程终止(我无法从文档中弄清楚)。在这种情况下,您将无法实现您想要的。然后,您可以考虑设置 websockets、使用 DRB 或其他方式来传递数据。

最新更新