Friday, September 19, 2014

Executing shell commands from groovy

Sometimes you want to run a shell command generated from groovy or just want to achieve something that's faster/simpler in the shell in comparison to doing it with groovy. One such case would be to get the number of git commits of a repo. The command for this is fairly simple:

$ git log --oneline | wc -l
179

Running shell commands from groovy is really easy too. Make a list and call 'execute()' on it - how awesome is that?

groovy:000> [ 'ls', '-1' ].execute()
===> java.lang.UNIXProcess@251104fb

So there's the system process groovy made for you. To get the output, simply access 'text':

groovy:000> [ 'ls', '-1' ].execute().text
===> buildSrc
infra
src
utils
vagrant

So as we've seen, there are 179 commits in that repo. Now to get this information from within a groovy script couldn't be simpler, but there's a gotcha! Since we're using a pipe '|' we can't simply do it the same way as above, but we must call a shell to execute that command since piping is a shell feature. So when everything is put together, we have this:

groovy:000> [ '/bin/sh', '-c', '/usr/bin/git log --oneline | wc -l' ].execute().text.trim()
===> 179

Also note the call to 'trim()' because there's a newline at the end of the output that I don't need. Calling a shell and passing the command as one string is much more readable than splitting everything into individual items. So to always be able to write this short and concise form (which is of course also copy-pasteable from and to the shell) just write it out, split by space and execute:

groovy:000> 'ls -1'.split(' ').execute().text.trim()
===> buildSrc
infra
src
utils
vagrant

And there you have it. Running shell commands from groovy couldn't be more convenient!

UPDATE

It turns out you can just call 'execute' on a string. So it's even simpler - at least this post now covers most (all?) ways to launch a command from groovy.

groovy:000> 'ls -1'.execute().text
===> buildSrc
infra
src
utils
vagrant