Groovy способ записывать вывод процесса - PullRequest
6 голосов
/ 27 августа 2009

Я хотел бы запустить длительный процесс командной строки в моем приложении Grails, записывать каждую строку вывода на консоль, когда она прибывает, и выполнять другие операции асинхронно, в то время как действия процесса и ведения журнала продолжаются. (В какой-то момент я захочу сделать что-то еще с каждой строкой вывода, например, войти в файл или найти определенные значения и инициировать другие действия. Но вход в консоль подойдет для целей этого вопроса.)

Ниже приведен код, который я придумал, чтобы сделать это. Это работает, но запуск потока logger без его явного завершения немного беспокоит меня - будет ли он завершен правильно? это может стать зомби? Я бы лучше сказал Groovy отправлять выходные данные процесса непосредственно в поток System.out - что-то вроде command.execute(outputStream=System.out) - но не нашел неблокирующего способа сделать это. Можете ли вы предложить лучший способ?

def runCommand(command) {
    def process = command.execute()
    def out = process.getInputStream()
    def logger = Thread.start { out.eachLine { println it } }
    process.waitForOrKill(TIMEOUT_IN_MILLIS)
    return process // use to get exit code et cetera
}

1 Ответ

11 голосов
/ 28 августа 2009

Глядя на Groovy документы для процесса , я обнаружил, что существует метод takeProcessOutput (OutputStream output, OutputStream error). Я попытался переписать ваш метод следующим образом, надеясь, что он будет неблокирующим:

def runCommand(command) {
  def process = command.execute()
  process.consumeProcessOutput(System.out, System.err)
  println 'requested consume output' //hoping this will come out first
  process.waitForOrKill(TIMEOUT_IN_MILLIS)
  return process // use to get exit code et cetera
}

Когда я запустил его в Windows XP с командой 'dir', я получил следующий вывод:

requested consume output
file1    file2  ...

Успех! :)

...