Get groovy for better shell scripts

I often use shell scripts to automate mundane, repeatable tasks on my computer. Since I’ve found Groovy, though, I have discovered a great way to make writing those scripts easier and more enjoyable. This is especially true if I have anything complex to do, and it saves me a LOT of time. Allow me to elaborate.

Getting started with command-line Groovy

Like many of the tools I advocate here, you’ll want to grab Cygwin for the best experience.

There are thorough instructions for getting Groovy running within the Groovy documentation. Basically you just download a ZIP, extract it where you want, and add a couple environment variables.

On some Linux distros you can just run:

sudo apt-get install groovy

Now you can start writing shell scripts in Groovy. Let’s write a little script to test it out:

#!/usr/bin/env groovy
println "Yay! I can finally be expressive now!"

Actually, there are a ton of ways to run Groovy, but I’m just going to focus on scripts for now.

chmod +x hello.groovy
./hello

Bash vs. Groovy example

Let’s say I want to have a script that can check my friends’ last X tweets so I don’t have to leave my command-line to check twitter.

#!/bin/bash
username=xxxxxxxx
password=yyyyyyyyyy
numTweets=10

#output tweets XML
curl --basic --user $username:$password http://twitter.com/statuses/friends_timeline.xml?count=$numTweets
#Some crazy AWK goes here... your assignment ;)

I really don’t want to read my tweets in XML. Being a Java guy, I wonder if there is a way we can harness it’s power. Groovy is basically enhanced Java so I can

#!/usr/bin/env groovy

username = "xxxxxxxx"
password = "yyyyyyyyyyy"
numTweets = "10"

//If we have an argument use it
if (args && args[0].toFloat() > 0) numTweets = args[0]

//Use twitter API with cURL
output = "curl -u $username:$password http://twitter.com/statuses/friends_timeline.xml?count=$numTweets".execute().text

//Parsing XML is Amazingly easy in Groovy
tweets = new XmlSlurper().parseText(output)
tweets.status.each { tweet->
    println "${tweet.user.name}: ${tweet.text}"
}

And run it just like any shell script:

chmod +x checktweets.groovy
./checktweets 15

Groovy can certainly do much more than deal with XML, it is a full-featured dynamic language with great expressiveness. It is simply satisfying to write, and you can do everything a shell script can do and more.

As an extra treat, here is a Groovy script to update your twitter status, tweet.groovy:

#!/usr/bin/env groovy

username = "xxxxxxxx"
password = "yyyyyyyyyyy"

if (args) {
    status = args[0]
    println "curl -u $username:$password -d status=\"${status}\" http://twitter.com/statuses/update.xml".execute().text
}

I personally have a /scripts directory in my home dir which I put on my path, so to run the previous script I just have to type:

tweet "Twitter is now Groovy, baby!"

Conclusion

Ok, so if you’re fairly savvy with your old-school shell scripting, I don’t expect you to switch to Groovy for simple tasks. I see 2 major cases for using it:

  • You need to do complex operations on data
  • You know Java better than your shell scripting

If you like Groovy and want to learn more, you might consider checking out the Groovy docs and basic Groovy exam I lead on JavaBlackBelt. It is kind of a learning exam as it demonstrates a bunch of really neat features of Groovy.

Tell me your thoughts!

If you liked this post, please help me share it

Responses (24)

  1. Mark Sanborn says:

    Nice write up with a useful example.

    So groovy is better if you already know Java syntax. I love the function name, “XmlSlurper”.

  2. @Mark:
    Thanks! I think it worth learning Groovy even if you don’t know Java, but it certainly helps.

    XmlSlurper is a built-in Groovy class for parsing XML. Fun, huh?

  3. Keith says:

    Very cool. Thanks for the Tutorial :)

  4. Mark Sanborn says:

    Eric,

    What would you say the main advantages are of groovy. What are the main selling points?

    I always have new programming languages on my someday/maybe list and would love to add more. :)

  5. @Mark:
    Well, Groovy is a dynamic language that runs on the JVM. Therefore you can do anything that Java can do, but there is less ceremony. Being a dynamic language like Javascript means that Groovy has closures and meta-object programming which means you can add functionality to basically anything at runtime.

    If you had to sell this to your manager, you might tell him that more is done with less code so it’s easier (faster) to write and maintain.

  6. Ptone says:

    I’m always trying to consolidate the languages I’m learning – what is the advantage of Groovy over Python?

    • @Ptone:
      Python is more mature than Groovy, BUT there are more editors that support Groovy out there. If you already know Java, then you have a great start with Groovy as the two can be syntacticly almost the same. Other than that, Groovy just feels lazier and I really like that.

  7. [...] 30, 2009 Eric Wendelin wrote: I often use shell scripts to automate mundane, repeatable tasks on my computer. Since I’ve found [...]

  8. devdanke says:

    Thanks man. I’ve been meaning to start using Groovy for shell scripting. You article is just what I needed to get me to do it.
    Cheers

  9. Ben says:

    Would you say that groovy is worthwhile for someone who knows ruby? I see them as being similar enough it would not be worth the effort to know both unless one was being forced on you. Your opinion?

    • Basically, if you or your team have anything to do with Java, Groovy is going to be more maintainable in the future. If it’s just for you and you know Ruby and not Java, you’re probably good.

  10. Binny V A says:

    I made this argument some time ago in my blog – use any language but not bash. I chose Perl – you went for groovy.

    I have not yet looked at groovy – because I kinda hate Java. Anyway, this post has inspired me – I’ll look into groovy ’soon’.

  11. Steve says:

    Cool demo, works really nice due to Twitter’s sweet api. But my questions is this–how do I run direct shell script commands in Windows from Groovy. Simple senario:
    I want to make 50 new directories, starting with “newDir” and numbered 01-50. How do I run the shell command “mkdir newDir${i}” from groovy? does anyone know?
    Thanks!

  12. Mika says:

    Groovy installation comes with a nice little interactive editor called groovyConsole, i’ve found it useful on windows, where the command line sucks. You can run scripts from it and its great for experimenting your scripts too. On windows i avoid native commands (i just dont like DOS) and use pure groovy like:

    50.times{ new File(“basedir/newDir${it+1}”).mkdir() }

    Using the java api has the advantage that scripts will be cross platform without effort. Disadvantage with groovyConsole is that for file operations, you will wind up using absolute paths for files.

  13. [...] Get groovy for better shell scripts Eric Wendelin’s Blog (tags: groovy) Blogroll [...]

  14. When dealing with command line options in groovy scripts I have learned to love the CliBuilder .. no more painful argument passing. IMHO a must for any groovy script that is intended for invocation from the command line.

  15. Jeff Barron says:

    You might want to check out Scala as well. http://scala-lang.org
    I’m a python guy myself but I love the idea of JVM languages. Scala runs on the JVM.
    :)

  16. Casey Watson says:

    Nice write-up Eric.

    This is much more appealing that using awk and bash.

  17. devdanke says:

    well, i was playing around with a groovy shell script. i’m sure you’ll agree, it’s pretty sophisticated:

    #!/bin/env groovy
    println “hey”

    my computer has a core 2 duo u9400 1.4 ghz cpu, 1 gb ram, win xp sp3, java 1.6.0_13, and groovy 1.6.3.

    when i call it directly from the bash prompt it takes 10 seconds to run. when i call it as an argument to groovy.bat, it takes 7 seconds.

    on the other hand, ruby ran it in less than 1 second and jruby ran it in 5 seconds.

    groovy’s 7-10 seconds performance is very slow and a big turn off compared to using other dynamic languages. my sense is that groovy’s start time is the problem.

    does anyone have ideas on how to make groovy run shell scripts faster?

  18. codecraig says:

    How about accessing those Twitter URL’s using HTTPS?

Leave a Reply