...
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:
- Cookbook Examples: Executing External Processes From Groovy
- PLEAC Process Management Examples
- A Groovy Shell called Groosh which builds upon Groovy's basic processing functionality