RunBash
This post is about running shell commands from within Groovy, specifically bash but it is easy to adapt to other shells. Groovy has built-in support for running commands like this:
"ls -l".execute()
That is about as simple as it can get and works great for many situations. However there is a key gotcha: execute()
simply executes the given command passing it whatever else is in the string as options to the command. The options are not passed through any shell (e.g. bash) for wildcard expansion or other transformations. As a result, you can not natively do something like:
"ls *.groovy".execute()
In this case, no shell sees the *
to expand it, and so the *
just gets passed to ls
exactly as an argument which ls
itself does not know how to interpret. To address this, we can create a shell process with ProcessBuilder
and pass the command to the shell for execution. A common use case for me is to want to just pipe the shell command’s output to stdout. With some Groovy meta-object programming we can make this a method of GString
and String
so that you can execute any kind of string simply by calling, for example, a .bash() method on the string. I have written a class called RunBash
which provides this function. With this class you can properly execute the ls *.groovy
example above with code like "ls *.groovy".bash()
. You can even execute more complicated shell scripts like:
To turn on this functionality it is necessary to call RunBash.enable()
first. So a full example using the durbinlib implementation of RunBash is:
Installation
You can obtain RunBash
with durbinlib, which is my kitchen-sink of everday classes and scripts. Simply clone, ant build, and add to CLASSPATH
and PATH
like:
####Source
To get an idea how this is implemented in Groovy code, a stripped-down but functional version of the class is shown below: