Groovy выполняет команды оболочки - PullRequest
145 голосов
/ 01 октября 2008

Groovy добавляет execute метод к String для упрощения выполнения оболочек;

println "ls".execute().text

но если произошла ошибка, то результат не выводится. Есть ли простой способ вывести как стандартную ошибку, так и стандартную? (кроме создания набора кода для; создать два потока для чтения обоих входных потоков, затем использовать родительский поток, чтобы дождаться их завершения затем преобразовать строки обратно в текст?)

Было бы неплохо иметь что-то вроде;

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

Ответы [ 7 ]

160 голосов
/ 01 октября 2008

Хорошо, решил сам;

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

отображает:

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

39 голосов
/ 01 октября 2008

"ls".execute() возвращает объект Process, поэтому "ls".execute().text работает. Вы должны иметь возможность просто прочитать поток ошибок, чтобы определить, были ли какие-либо ошибки.

В Process существует дополнительный метод, позволяющий передать StringBuffer для извлечения текста: consumeProcessErrorStream(StringBuffer error).

Пример:

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

println proc.text
println b.toString()
27 голосов
/ 05 сентября 2012
// 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()
}
19 голосов
/ 16 августа 2014

Чтобы добавить еще одну важную информацию к приведенным выше ответам -

Для процесса

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, поскольку последний является блокирующим вызовом ( ТА вопрос по причине ).

14 голосов
/ 09 февраля 2017

Я нахожу это более идиоматическим:

def proc = "ls foo.txt doesnotexist.txt".execute()
assert proc.in.text == "foo.txt\n"
assert proc.err.text == "ls: doesnotexist.txt: No such file or directory\n"

Как уже упоминалось в другом посте, это блокировка вызовов, но поскольку мы хотим работать с выводом, это может быть необходимо.

5 голосов
/ 22 сентября 2016
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]
0 голосов
/ 13 июля 2017
command = "ls *"

def execute_state=sh(returnStdout: true, script: command)

но в случае сбоя команды процесс завершится

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...