bash_shell

Automate everything (practical uses of Bash part 1)

I find that having a bias towards automation makes life a lot easier. I’ve been writing more and more scripts the farther along I go in my career. The time it takes to write a little script is hardly anything compared to the time it saves. I just can’t stay comfortable with typing long commands anymore. There’s a certain point where it just makes sense to script a task and that point usually comes only the second or third time I do it.

Usually I write scripts in Bash. Whether I’m on my mac or on my linux box, Bash is there.

So what are some practical uses of Bash? Here’s a few.

Command line arguments
I don’t like having to type tail -f /usr/local/tomcat/logs/webapp.log so I just make a quick bash script that replaces the filename with the webapp whose log I want to tail. I pass it in as a command line argument which bash just refers to as $1.

taillog.sh

#!/bin/bash
tail -F /usr/local/tomcat/logs/$1.log

I probably also alias it:

$ alias taillog=/where/I/store/my/scripts/taillog.sh

Then I can use it like:

$ taillog webapp

Seems like a really subtle difference but the improvement in actual day-to-day development is surprising.

Check if a file or directory exists
I often want to know if a file or directory exists before performing an action. For example, if you pass a non-existent file name to the preceding script it will print out a message and then hang there until you hit Ctrl+C.

$ taillog notexists
tail: cannot open ‘/usr/local/tomcat/logs/notexists.log’ for reading: No such file or directory
^C $ 

It should be updated using an if statement with the -f flag to check that the file exists:

#!/bin/bash
file=/usr/local/tomcat/logs/$1.log
if [ ! -f "$file" ]; then
  echo "The file $file doesn't exist"
  exit 1
fi

tail -F $file

The -d flag is used similarly. For example, I don’t know why you’d want to but, you can check if you have a home directory

checkhome.sh

#!/bin/bash
if [ -d "$HOME" ]; then
  echo "Checks out: you have a home directory at $HOME"
fi

Wait for something
If I want to, for example, restart Tomcat, and wait until my app is up and healthy, I might write a script like this:

#!/bin/bash
# restart tomcat in the background
sudo systemctl restart tomcat &

# wait until health URL is up
while [ ! "$(curl -s http://localhost:8080/health)" ]; do
  echo -n "."
  sleep 1
done
curl -s http://localhost:8080/health

The first trick here is that the ampersand (&) character can be put on the end of any line to make it execute in the background.

The second trick is constructing a loop where we output one period and then sleep one second, as long as there’s no output from the curl command against our health check URL. The -s flag on curl is really important here because without it curl outputs something like the below:

curl: (6) Could not resolve host: localhost; Name or service not known

Obviously we want to be able to check the condition that nothing is output until the actual response comes back, so the -s flag helpfully does that for us.

OK that’s enough for today. I’ll pass along some other practical uses of Bash another time.

One thought on “Automate everything (practical uses of Bash part 1)

Leave a Reply

Your email address will not be published. Required fields are marked *