我使用open3在Ruby中创建了一个帮助器方法来执行JRuby的DOS命令......
def ShellUtils.execute_cmd(cmd)
$ERRORS = ['Invalid type','Invalid path']
out = nil
err = nil
Open3.popen3(cmd) {|stdin, stdout, stderr, wait_thr|
out = stdout.read
err = stderr.read
unless err.nil?
err = $ERRORS.detect {|e| err.include? e }
end
out.each {|line| logger.info "#{line}"} unless out.nil?
err.each {|line| logger.error #{line}"} unless err.nil?
}
return out, err
end
如果正在执行的进程的任何部分无效,则会输出错误消息及其用法。下面是在DOS中执行进程时的正常错误输出,没有涉及JRuby或Ruby ......
C:\PROJECTS\bin>import.bat -su -types ws,v
Invalid type. Valid ones are: folder, datasource...
Usage:
import -f path-to-file [-s servers-file | -h server...
但是当我使用import.bat
和JRuby执行ShellUtils.execute_cmd()
时,日志永远不会捕获错误消息Invalid type. Valid ones are...
,我只看到错误日志的使用输出。我不明白为什么因为使用和错误消息来自import.bat
。我检查了out
和err
对象,但都没有包含错误字符串。
我只需要检测错误消息以向调用者发出进程失败的信号,但是在错误日志中没有该字符串时,很难知道发生了什么。
答案 0 :(得分:1)
编辑:
看了一下你的方法后我觉得你错了。你能试试这个:
def ShellUtils.execute_cmd(cmd)
out = nil
err = nil
Open3.popen3(cmd) {|stdin, stdout, stderr, wait_thr|
out = stdout.read
err = stderr.read
unless err.nil?
err = err.split("\n")
puts err.inspect
err = err.select {|e| e =~ /Invalid/ }
end
out.each {|line| logger.info "#{line}"} unless out.nil?
err.each {|line| logger.error "#{line}"} unless err.nil?
}
return out, err
end
与其说是一种解决方案。您可能想尝试systemu。对于我来说,这对jruby非常有用:
require 'rubygems'
require 'systemu'
cmd = "#{File.expand_path('../', __FILE__)}/import.bat -su -types ws,v "
status, stdout, stderr = systemu cmd
p [ status, stdout, stderr ]
答案 1 :(得分:0)
也许您的进程尚未写入错误流。在阅读输出之前尝试等待它完成:
Open3.popen3 cmd do |stdin, stdout, stderr, thread|
thread.join # Wait for the process to finish
output, error = stdout.read, stderr.read
# ...
end