[groovy-user] printing the output from "some command".execute()

2,258 views
Skip to first unread message

Ed Young

unread,
Dec 2, 2009, 12:49:18 AM12/2/09
to us...@groovy.codehaus.org
I'm trying to display the result log data of a long running process that I've kicked off using groovy's String.execute() method. 

I can do this for example:

command = "ls -la"
Process proc = command.execute().text

And I get the out put as expected. 

However, if the command is some long running process like a slowly running TestNG test which prints out logging data as it runs, I'm unable to execute it and see the logging in real time. 

I've tried variations on this: 

String command "Some long running command that ouptuts logging info"

Process proc = command.execute().text

StringBuffer outBuff = new StringBuffer()

proc.consumeProcessOutputStream(outBuff)

while(outBuff != "")
{
    println outBuff.toString()
}


Is this possible?

 

jim northrop

unread,
Dec 2, 2009, 5:36:57 AM12/2/09
to us...@groovy.codehaus.org
HI
look here: http://groovy.codehaus.org/groovy-jdk/

i've used the waitFor method before, but do not examples just now. Seems to block the process till process EOJ

k/r
jim

2009/12/2 Ed Young <e...@summitbid.com>

Joey Gibson

unread,
Dec 2, 2009, 8:06:16 AM12/2/09
to us...@groovy.codehaus.org
On Wed, Dec 2, 2009 at 12:49 AM, Ed Young <e...@summitbid.com> wrote:
I'm trying to display the result log data of a long running process that I've kicked off using groovy's String.execute() method. 

I can do this for example:

command = "ls -la"
Process proc = command.execute().text

And I get the out put as expected. 

However, if the command is some long running process like a slowly running TestNG test which prints out logging data as it runs, I'm unable to execute it and see the logging in real time. 


In one of my scripts, I do some svn commands and then do several builds using Maven. I needed to see the output as it was happening and ran into the same problems you did. Here's how I solved it:

def executeProc(cmd) {
  def proc = "cmd /c ${cmd}".execute()
 
proc.in.eachLine {line ->
println line
}

  println proc.err.text

proc.exitValue()
}

// Test it
def cmd = "cd ${my_dir} && mvn.bat ${skip_tests} ${clean} install"


This code will let me see whatever is being sent to stdout as it happens. I reserved the displaying of stderr messages until the end. If you need to see both at the same time, the only way I think you could do that is if inside the string that is your command you redirect stderr to stdout. You can see that my script is running on Windows, but the same things should work on a Mac or Linux; the only difference is your command strings would be different and you wouldn't do the "cmd /c" inside the executeProc function.

Joey 

--
Blog: http://joeygibson.com
Twitter: http://twitter.com/joeygibson
FriendFeed: http://friendfeed.com/joeygibson
Facebook: http://facebook.com/joeygibson

Tim Yates

unread,
Dec 2, 2009, 8:06:44 AM12/2/09
to us...@groovy.codehaus.org
Sorry, meant to reply to this sooner but got bogged down.

I do this sort of thing:

 def proc = "/path/to/longRunningProcess".execute( null, new File( "/path/to/workingDirectory" ) )
 new File( "/path/to/output.txt" ).withWriter { outFile ->
   proc.in.eachLine { line ->
     def tokens = line.tokenize( "\t" )
     outFile.writeLine "${tokens.join(',')}"
   }
 }
 proc.waitFor()

So that executes "longRunningProcess"  with the working directory set to whatever you want, then reads each line of output, splits it up based on tabs, and writes it back out to output.txt as comma separated data

Hope this is what you meant (and hope it helps)

Tim

PS:  That code may not run, as I have stripped it down from my actual code, but should give you the idea of how I do it)

Ed Young

unread,
Dec 3, 2009, 11:47:42 AM12/3/09
to us...@groovy.codehaus.org
I came up with a Groovy solution (with some help from a colleague-Thanks Daniel!)

What I'm doing is programmatically executing a TestNG test suite in it's own jvm. It takes a long time, and I want to see the output as it executes. 

def command = """java -Xms512m -Xmx1024m -classpath test-suite-package-3.jar org.testng.TestNG -testjar test-suite-package-3.jar -d ./test-output-final/"""
Process proc = command.execute()                                                // executes the command 

OutputStream outputStream = new FileOutputStream("stdout.txt")
OutputStream errorStream  = new FileOutputStream("stderror.txt")
proc.waitForProcessOutput(outputStream, errorStream)                     // NOTE: since groovy 1.6.5

println "Executing a testng jar"

The above will execute a TestNG test suit,  and write the normal process output to stdout.txt and errors to stderror.txt. The waitForProcessOutputWill block while processing, but will write to the output files as it goes. The files can be tailed to monitor the progress. The script will return when the process exits, and the files will serve as an execution log (in addition to the TestNG reporting)
--
- Ed
Reply all
Reply to author
Forward
0 new messages