Writing clearer Bash scripts
|
Picket Fences
Even if you're under time pressure, comment your scripts. After a week, you will still know what the script is doing and why. At the beginning of the script, briefly identify its purpose:
#!/bin/bash # # Captures screenshots
Some style guides recommend adding more, such as the author and version number. The comment hash mark (# ) should be followed on the line with a space character before adding the comment text so that the comments are easier to locate.
Each function should have its own comments that briefly identify its purpose and methods, all passed arguments and returned values, and possibly which global values the function changes. Google recommends a structure like that shown in Listing 5.
Listing 5
Recommended Structure
####################################### # Captures screenshots # Globals: # LOCATION # FILENAME # Arguments: # None # Returns: # None ####################################### screenshot() { ... }
If you're tempted to write a short novel as comments, your function is probably overly complex. You might want to think about splitting the function into smaller ones.
Finally, you should include comments for code blocks that might not be self-explanatory. Good candidates are loops and if queries. Comments don't need to be too detailed, and you certainly don't need to comment each line. Some style guides suggest adding comments after the command line itself instead of on separate lines:
NUMBER=100 # False # True NUMBER=100
The comments should never just echo the code but simply describe its purpose. Instead of for 1 through 100 calls image and waits 3 seconds , write captures a screenshot every 3 seconds . Providing a good comment is often as hard as giving variables appropriate names.
If you've just quickly written the code with the intention of revising it soon after, you can add comments to target your further revision with a TODO, such as:
# TODO (tim@example.com) # Calculate pseudo-random number
In the parentheses give the contact person's name, ideally as an email address. Whoever sees the script later can then contact you. Some text editors even highlight lines beginning with #TODO so that they stand out. Apart from TODO , some style guides recommend adding FIXME for buggy sections or XXX for places needing particular attention.
Launch Pad
Remember to add the necessary rights to execute the script:
$ chmod +x <Script>.sh
Google advises omitting the .sh extension. None of the linked script files should have the execution bits set or retain the .sh in filenames. Filenames should all be lowercase. If you are concatenating words in filenames, separate them with underscores and not hyphens, such as take_screenshots . Remember not grant the script any SUID or SGID privileges to avoid risk of security breaches or misuse.
The script should provide users with termination information as to success or interrupted processing. In the latter case, it should provide a meaningful message on the STDERR channel. This approach allows all messages to be targetedly redirected later. End the script on error with exit 1 , otherwise, with exit 0 . That way the script can be more easily integrated into other projects.
Listing 6 shows the cryptic script in Listing 1 in its revised and improved form. If comments are in a foreign language, it's best to translate them into English. By the way, you can reduce the code in Listing 6 onto one line with a current version of ImageMagick:
Listing 6
Revised and Improved Script
#!/bin/bash # # Captures screenshots NUMBER_IMAGES=100 WAITING_PERIOD_SECONDS=3 LOCATION="." PREFIX_FILENAME="shot" # captures a screenshot every 3 seconds # but not more than specified for i in $(seq 1 ${NUMBER_IMAGES}); do import -window root "${LOCATION}/${PREFIX_FILENAME}${i}.png"; sleep ${WAITING_PERIOD_SECONDS} done; exit
$ import -window root -snaps 100 -pause 3 shot.png
As you can see, referencing documentation or a man page can often save you from writing a script to begin with.
Buy this article as PDF
Pages: 4
(incl. VAT)