I would like to start a long-running command-line process in my Grails application, log each line of output to the console when it arrives, and do other stuff asynchronously, while the process and logging activities keep going. (At some point, I'll want to do something else with each line of output, like log to a file or look for certain values and trigger other actions. But logging to the console is fine for the purposes of this question.)
Below is the code I came up with to do this. It works, but starting the logger
thread without expressly terminating it bothers me a bit - will it terminate properly? can it become a zombie? I'd rather tell Groovy to send process output directly to the System.out
stream - something like command.execute(outputStream=System.out)
- but haven't found a non-blocking way to do that. Can you suggest a better way?
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
}
You can print the current value of a variable with the println function.
Looking at the Groovy docs for Process, I saw that there was a method consumeProcessOutput(OutputStream output, OutputStream error). I tried rewriting your method in the following way, hoping that it would be non-blocking:
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
}
When I ran it on Windows XP with the command 'dir', I got the following output:
requested consume output
file1 file2 ...
Success! :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With