以下代码简化了我目前的情况。我有一个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}}调用或不使用它)都不起作用-输出为空。
答案 0 :(得分:1)
@Ry指出in the comments,在IRB中$stdout.sync
默认为true
,但这对于脚本来说不一定相同。
因此,您应该设置$stdout.sync = true
以确保防止缓冲。