我在nohup
下运行时看到一些令人困惑的Ruby脚本行为。基本上我是这样做的:
require 'logger'
logger_file = open('/mnt/dbsdata/output.log', File::WRONLY | File::APPEND | File::CREAT)
LOGGER = Logger.new(logger_file)
LOGGER.level = Logger::INFO
def run_command(cmd,display=true)
if display
LOGGER.info "Executing: #{cmd}"
end
output = `#{cmd} 2>&1` ; results=$?.success?
if ! results
LOGGER.error "FAILED to execute #{cmd}"
LOGGER.error output
return false
end
return true
end
begin
run_command("some_longrunning_command", true)
run_command("some_other_longrunning_command",true)
# etc...
end
这里奇怪的是,当使用上面的Logger和正常puts
到STDOUT(nohup.out)时,输出时间都是关闭的。我想我可以拖尾日志文件并查看实时日志消息(日志消息,执行命令,重复),但是发生的事情是大量刷新消息以便一次性记录许多陈旧消息,很久他们的命令就是已经执行并完成。
从shell执行脚本时这样:
`nohup ruby myscript.rb &`
如果不在nohup下运行,则表现如预期。
任何人都有这方面的经验并知道一个好的解决方法吗?
答案 0 :(得分:2)
我不能肯定地说,但这听起来像是一个IO sync
问题。 I / O通常是为了速度而缓冲的。 RAM比磁盘快很多,因此读取和写入会暂时存储,直到代码请求数据,或者磁盘能够接收它。 Ruby的IO类有sync=
方法,可让你告诉Ruby在写入时立即刷新缓冲区。
这应该有效:
logger_file = open('/mnt/dbsdata/output.log', File::WRONLY | File::APPEND | File::CREAT)
logger_file.sync = true
LOGGER = Logger.new(logger_file)
LOGGER.level = Logger::INFO
为简单起见,您可以使用以下方法为输出创建正确的模式:
logger_file = File.open('/mnt/dbsdata/output.log', 'a')
答案 1 :(得分:0)
听起来像缓冲。尝试登录到stderr并查看是否有帮助。