为什么我不期望Ruby STDOUT缓冲?

时间:2019-12-20 07:44:18

标签: ruby pipe stdout jq

以下代码简化了我目前的情况。我有一个JSON日志源,我不断用puts提取并写入stdout。

#!/usr/bin/env ruby

require "json"

loop do
  puts({ value: "foobar" }.to_json)
  sleep 1
end

我希望能够将此脚本的输出通过jq传递到./my_script | jq 进行进一步处理,但要使用unix管道,以“流”友好的方式进行。像这样运行上面的代码:

exit

导致输出为空。但是,如果我在sleep调用之后放置jq语句,则输出将按预期通过管道发送到$stdout.flush。通过在puts调用之后调用$stdout.sync,我能够解决此问题。虽然现在可以正常工作,但我不确定为什么。 true默认设置为$stdout.flush(请参阅IO#sync)。在我看来,如果启用了同步,则Ruby应该不进行输出缓冲,并且不需要调用tail-确实如此。

我的后续问题是关于使用jq而不是tail。在我看来,我应该能够像将文本流输送到jq一样,将文本流输送到$stdout.flush中,但是两种方法(使用{{1}}调用或不使用它)都不起作用-输出为空。

1 个答案:

答案 0 :(得分:1)

@Ry指出in the comments,在IRB中$stdout.sync默认为true,但这对于脚本来说不一定相同。

因此,您应该设置$stdout.sync = true以确保防止缓冲。