我寫執行shell命令的功能,並返回其退出代碼,stdout和stderr。使用popen3無法正確處理STDOUT和STDERR輸出?
問題是,此函數無法正確捕獲STDOUT和STDERR輸出。
def sh(*args)
options = args[-1].respond_to?(:to_hash) ? args.pop.to_hash: {}
options = { :timeout => 0, :sudo => false }.merge(options)
cmd = options[:sudo] == false ? args[0] : "sudo " << args[0]
begin
stdin, stdout, stderr, wait_thr = Open3.popen3(cmd)
pid = wait_thr[:pid]
out_buf = ""
err_buf = ""
start = Time.now
# Manually ping the process per 0.2 second to check whether the process is alive or not
begin
out_buf << stdout.read_nonblock(4096)
err_buf << stderr.read_nonblock(4096)
# kill the process if it timeouts
if options[:timeout] != 0 && (Time.now - start) > options[:timeout]
Process.kill("KILL", pid)
Process.detach(pid)
raise RuntimeError, "process with pid #{pid} timed out with #{options[:timeout]} seconds."
end
sleep 0.2
rescue IO::WaitReadable, EOFError
end while wait_thr.alive?
rescue => e
NtfLogger.warn("sh '#{args}' executed with failure: #{e}")
ensure
if wait_thr.nil?
return 1, out_buf, err_buf
else
return wait_thr.value.exitstatus, out_buf, err_buf
end
end
end # end of sh
請問有人能幫我弄清楚是什麼問題?
你是什麼意思「無法捕捉」在這裏嗎?它超時嗎?什麼? – rogerdpack
我的意思是它經常從stdout和stderr丟失一些文本。 – TieDad