Friday, October 28, 2011

Shell Scripting Tips

Process Automation

We like Bash.
We like Cron.

The combination of Bash and Cron makes our department run more smoothly by giving my a huge degree of flexibility for automation. For instance:
  • I've got a cron job that checks for FreeBSD updates on each of our FreeBSD servers. When an update is available, I get an email.
  • We're paid on a bi-weekly basis. I have a weekly cron job that calls a script to remind me to turn in my time card on every 2nd run.
  • We back up our VMWare ESXi machines each weekend. Cron calls a backup script that enumerates our VMs, then backs them up to our NFS server.
  • We use a Hanoi Rotation for our backup tapes. My predecessor wrote a Heroku app to calculate the weekly tape rotation (whichtape.heroku.com). I have a cron job that gets the tape label from the web page and emails it to me with a reminder to change out the tape.
This is a very potent combination. We've run into a few gotchas--mostly foibles in Bash--that produce script behavior which is quite odd if you don't know what you're looking for.


Two things that will make you shell scripting life easier:
  1. "Internal Field Separator:" When using "for i in" loops to parse lists, Bash uses a field separator value stored in the IFS variable. By default, this consists of space, tab, and newline. Frequently (almost always), I'm using a loop to parse strings containing spaces, and want the field separator to consist solely of a newline character. The behavior can be achieved by setting the IFS variable to the newline character at the beginning of your script:
  2. IFS=$'\n'

  3. while [ $TRIP -ne SOMESTRING ] ; do ; done  is great for delaying execution of a script until $TRIP matches a defined value. It's even better when your strings are validated:
  4. while [ "$TRIP" -ne "SOMESTRING" ] ; do ; done

Happy Automating!