Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Executing

...

External

...

Processes

...

Groovy

...

provides

...

a

...

simple

...

way

...

to

...

execute

...

command

...

line

...

processes.

...

Simply

...

write

...

the

...

command

...

line

...

as

...

a

...

string

...

and

...

call

...

the

...

exectue()

...

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}"
{code}
The {{

The execute()

...

method

...

returns

...

a

...

java.lang.Process

...

instance

...

which

...

will

...

subsequently

...

allow

...

the

...

in/out/err

...

streams

...

to

...

be

...

processed

...

and

...

the

...

exit

...

value

...

from

...

the

...

process

...

to

...

be

...

inspected

...

etc.

...

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 }
{code}

Hint:

...

in

...

Groovy

...

1.5.5

...

the

...

eachLine

...

method

...

is

...

not

...

available

...

on

...

InputStream.

...

Earlier

...

or

...

later

...

version

...

will

...

have

...

that

...

method.

...

As

...

an

...

alternative

...

you

...

can

...

use

...

process.in.newReader().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}"
{code}

you

...

will

...

get

...

IOException saying  "Cannot

...

run

...

program

...

"dir":

...

CreateProcess

...

error=2,

...

The

...

system

...

cannot

...

find

...

the

...

file

...

specified."

...

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}"
{code}

Also,

...

because

...

this

...

functionality

...

currently

...

make

...

use

...

of

...

java.lang.Process

...

under

...

the

...

covers,

...

the

...

deficiencies

...

of

...

that

...

class

...

must

...

currently

...

be

...

taken

...

into

...

consideration.

...

In

...

particular,

...

the

...

javadoc

...

for

...

this

...

class

...

says:

...

Because

...

some

...

native

...

platforms

...

only

...

provide

...

limited

...

buffer

...

size

...

for

...

standard

...

input

...

and

...

output

...

streams,

...

failure

...

to

...

promptly

...

write

...

the

...

input

...

stream

...

or

...

read

...

the

...

output

...

stream

...

of

...

the

...

subprocess

...

may

...

cause

...

the

...

subprocess

...

to

...

block,

...

and

...

even

...

deadlock

...

Because

...

of

...

this,

...

Groovy

...

provides

...

some

...

additional

...

helper

...

methods

...

which

...

make

...

stream

...

handling

...

for

...

processes

...

easier.

...

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()
{code}

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

...

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

{code}
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

{code}
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

{code}
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}

h4. Further Information

See also:

* Cookbook Examples: [Executing External Processes From Groovy]
* PLEAC [Process Management|http://pleac.sourceforge.net/pleac_groovy/processmanagementetc.html] Examples
* A Groovy Shell called [Groosh] which builds upon Groovy's basic processing 

Further Information

See also: