Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

Groovy provides a simple way to execute command line processes. Simply write the command line as a string and call the exectueexecute() method. E.g., on a *nix machine (or a windows machine with appropriate *nix commands installed), you can execute this:

Code Block

def process = "ls -l".execute()
println "Found text ${process.text}"

...

e.g. here is the same command as above but we will now process the resulting stream a line at a time

Code Block

def process = "ls -l".execute()
process.in.eachLine { line -> println line }

...

Remember that many commands are shell built-ins and need special handling. So if you want a listing of files in a directory on a windows machine and if you write

Code Block

Process p = "dir".execute()
println "${p.text}"

...

This is because "dir" is built-in to the windows shell (cmd.exe) and can't be run as a simple executable. Instead, you will need to write:

Code Block

Process p = "cmd /c dir".execute()
println "${p.text}"

...

Here is how to gobble all of the output (including the error stream output) from your process:

Code Block

def p = "rm -rf */*.tmp".execute()
p.consumeProcessOutput()

There are also variations of consumeProcessOutput including one which takes output and error StringBuffers, another which takes output and error ditto for InputStreams and variations for StringBuffers, Writers and InputStreams which handle just the output stream or error stream individually. In addition, these there is a pipeTo command (mapped to '|' to allow overloading) which lets the output stream of one process be fed into the input stream of another process.

Here are some examples of use:

Code Block

proc1 = 'ls'.execute()
proc2 = 'tr -d o'.execute()
proc3 = 'tr -d e'.execute()
proc4 = 'tr -d i'.execute()
proc1 | proc2 | proc3 | proc4
proc4.waitFor()
if (proc4.exitValue())
    print proc4.err.text
else
    print proc4.text
Code Block

def sout = new StringBuffer()
def serr = new StringBuffer()
proc2 = 'tr -d o'.execute()
proc3 = 'tr -d e'.execute()
proc4 = 'tr -d i'.execute()
proc4.consumeProcessOutput(sout, serr)
proc2 | proc3 | proc4
[proc2, proc3].each{ it.consumeProcessErrorStream(serr) }
proc2.withWriter { writer ->
    writer << 'testfile.groovy'
}
proc4.waitForOrKill(1000)
println 'sout: ' + sout
println 'serr: ' + serr
Code Block

def sout = new StringBuffer()
def serr = new StringBuffer()
proc1 = 'gzip -c'.execute()
proc2 = 'gunzip -c'.execute()
proc2.consumeProcessOutput(sout, serr)
proc1 | proc2
proc1.consumeProcessErrorStream(serr)
proc1.withWriter { writer ->
    writer << 'test text'
}
proc2.waitForOrKill(1000)
println 'sout: ' + sout // => test text
println 'serr: ' + serr
Code Block

def initialSize = 4096
def outStream = new ByteArrayOutputStream(initialSize)
def errStream = new ByteArrayOutputStream(initialSize)
def proc = "ls.exe".execute()
proc.consumeProcessOutput(outStream, errStream)
proc.waitFor()
println 'out:\n' + outStream
println 'err:\n' + errStream
Code Block

def out = new StringBuilder()
def err = new StringBuilder()
def proc = "ls".execute()
proc.waitForProcessOutput(out, err)
if (out) println "out:\n$out"
if (err) println "err:\n$err"

...