Writing clearer Bash scripts

Slashdot it! Delicious Share on Facebook Tweet! Digg!

In the Break

In a case statement, list the alternatives indented by two spaces. The patterns and their values should each be on their own line. Listing 3 shows an example. Link multiple commands when necessary with a pipe, such as ls -la | grep TODO.

Listing 3

Sample case Statement

case "${auto}" in
  porsche)
    motor="hum"
    echo "${motor}"
    ;;
  *)
    echo "No known car"
    ;;
esac

The pipe symbol should have a space characters on both sides. If the chain consists of more than two elements, it's best to enter each element on a separate line, with successive lines indented as shown below:

<command1> | <command2> | <command3>

Long parameter lists should follow the same principle:

./configure --prefix=$HOME --enable-audio --enable-video

Furthermore, Google recommends wrapping lines at 80 characters, although other style guides allow for a slightly longer line length. These limits allow for easier printing and fewer scrolling hassles (Figure 3).

Figure 3: The terminal wraps lines at 80 characters. Many editors (e.g., nano in the background) truncate the line when the right edge is reached.

Storage Locations

If you name your variables with short, cryptic names, like a, what they represent can be deduced only in context, and then only with great difficulty.

Therefore, you should choose meaningful variable names that describe their contents. A variable named filename certainly can't be misinterpreted down the road. The names should be short and concise, consisting of no more than 31 characters. Take the pain of choosing suitable variable names, and it will pay off in the long run.

Most style guides suggest using lowercase variable names ( count) and uppercase constants ( NUMBER) . The constants should be defined as a group at the beginning of the script. Avoid using names that are reserved words for environmental variables.

You can find a list of these words on the web [3]. To be on the safe side, give constants a prefix, such as ABC_COUNT. If the name consists of multiple words, separate them with an underscore character, such as letter_greeting.

You're also advised to use singulars and plurals per context, which helps especially in loops:

for amount in ${prices}; do
  echo ${amount}
done

Always enclose variables in curly brackets, such as ${last_name}. Enclose strings that include variables in quotes:

name="Mr. ${last_name}"

In that way, Bash correctly replaces the variable. With the new replacement names, the script in Listing 1 begins to gain clarity. Listing 4 shows a group of images that the script will process in certain ways.

Listing 4

Images for Processing

#!/bin/bash
NUMBER_IMAGES=100
WAITING_PERIOD_SECONDS=3
LOCATION="."
PREFIX_FILENAME="shot"
for i in `seq 1 ${NUMBER_IMAGES}`; do
  import -window root "${LOCATION}/${PREFIX_FILENAME}${i}.png";
  sleep ${WAITING_PERIOD_SECONDS}
done;
exit

Numbers appear in quotes only if they're part of a string. To ensure that false values don't enter calculations, always initialize variables. If the content of a variable shouldn't change, mark it explicitly with the keyword readonly :

result = do_something
readonly result

If a subsequent process changes the variable, Bash returns an error, which saves you a lengthy error search.

Buy this article as PDF

Express-Checkout as PDF

Pages: 4

Price $0.99
(incl. VAT)

Buy Ubuntu User

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content