199

Groovyは、シェルの実行をかなり簡単にするためのexecuteメソッドを追加します。String

println "ls".execute().text

ただし、エラーが発生した場合、結果の出力はありません。 標準エラーと標準の両方を取り除く簡単な方法はありますか? (一連のコードを作成する以外に、2つのスレッドを作成して両方の入力ストリームを読み取り、親ストリームを使用してそれらが完了するのを待ってから、文字列をテキストに変換しますか?)

次のようなものがあると便利です。

 def x = shellDo("ls /tmp/NoFile")
 println "out: ${x.out} err:${x.err}"
4

7 に答える 7

251

わかりました、自分で解決しました。

def sout = new StringBuilder(), serr = new StringBuilder()
def proc = 'ls /badDir'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout\nerr> $serr"

表示:

out> err> ls: cannot access /badDir: No such file or directory

于 2008-10-01T19:20:26.123 に答える
60

"ls".execute()Process動作する理由であるオブジェクトを返します"ls".execute().text。エラーストリームを読み取って、エラーがあったかどうかを判断できるはずです。

テキストを取得するためにProcessaを渡すことができる追加のメソッドがあります。StringBufferconsumeProcessErrorStream(StringBuffer error)

例:

def proc = "ls".execute()
def b = new StringBuffer()
proc.consumeProcessErrorStream(b)

println proc.text
println b.toString()
于 2008-10-01T19:16:06.960 に答える
36
// a wrapper closure around executing a string                                  
// can take either a string or a list of strings (for arguments with spaces)    
// prints all output, complains and halts on error                              
def runCommand = { strList ->
  assert ( strList instanceof String ||
           ( strList instanceof List && strList.each{ it instanceof String } ) \
)
  def proc = strList.execute()
  proc.in.eachLine { line -> println line }
  proc.out.close()
  proc.waitFor()

  print "[INFO] ( "
  if(strList instanceof List) {
    strList.each { print "${it} " }
  } else {
    print strList
  }
  println " )"

  if (proc.exitValue()) {
    println "gave the following error: "
    println "[ERROR] ${proc.getErrorStream()}"
  }
  assert !proc.exitValue()
}
于 2012-09-04T20:06:40.313 に答える
26

上記の回答にもう1つ重要な情報を追加するには-

プロセスの場合

def proc = command.execute();

常に使用しようとする

def outputStream = new StringBuffer();
proc.waitForProcessOutput(outputStream, System.err)
//proc.waitForProcessOutput(System.out, System.err)

それよりも

def output = proc.in.text;

後者はブロッキング呼び出しであるため、groovyでコマンドを実行した後に出力をキャプチャします(SOの理由の質問)。

于 2014-08-16T06:08:39.850 に答える
8
def exec = { encoding, execPath, execStr, execCommands ->

def outputCatcher = new ByteArrayOutputStream()
def errorCatcher = new ByteArrayOutputStream()

def proc = execStr.execute(null, new File(execPath))
def inputCatcher = proc.outputStream

execCommands.each { cm ->
    inputCatcher.write(cm.getBytes(encoding))
    inputCatcher.flush()
}

proc.consumeProcessOutput(outputCatcher, errorCatcher)
proc.waitFor()

return [new String(outputCatcher.toByteArray(), encoding), new String(errorCatcher.toByteArray(), encoding)]

}

def out = exec("cp866", "C:\\Test", "cmd", ["cd..\n", "dir\n", "exit\n"])

println "OUT:\n" + out[0]
println "ERR:\n" + out[1]
于 2016-09-22T03:09:58.100 に答える