3 Bash scripting techniques every Linux user should know
Have you been thinking about biting the bullet and learning Bash scripting ? Or perhaps you're like me, and you're always looking for ways to improve. I have three tips that will improve every Bash script you write.
Passing arguments, writing a help menu, and debugging can be burdensome. However, the getopts command, Heredoc, and the "set -x" option are common solutions that not everybody knows about. Let's tackle that problem and learn how these things can improve your Bash scripts.
Use a Heredoc to specify a help menu
When you execute a script months after you wrote it, the first thing you will need is a help menu. Without that, you need to dig into the source code to jog your memory, which is an unnecessary hassle.
When I started writing help menus in Bash, I used a function that ran dozens of echo statements.
Even though I aligned the menu elements to make them more readable, a Heredoc is far superior:
The code is tidier, more readable, easier to write, and without special characters (e.g., "") to format it. To make your life easier, you should prefer a Heredoc over separate echo statements.
Also, notice the use of "$(basename $0)," which extracts the filename from the script path so that our help menu displays the name of the script.
-
"$0" is the script path.
-
"basename" extracts the filename from a path.
Parse command line arguments like a pro
Now that we have a menu, we need to process the arguments. The most common and easiest way is to access the positional parameters provided by Bash.
However, that approach becomes complex when handling options (aka flags) and values. The getopts command is the go-to solution, and it's built into Bash. Below, I have expanded the earlier help menu example to allow us to process options:
Accepting basic options
The basic form of the getopts command is:
The options string ("optstring") is how we specify available options. If we want to accept the -a, -b, and -c options, then we specify the option string as follows:
There are three facts we can use to our advantage:
-
The option variable ("optvar") stores the option name currently being processed (e.g., a, b, or c).
-
When complete, getopts returns a number greater than zero.
-
A while loop will continue until it receives a falsy value, like an exit code of 1.
Simply put, the following code will process each option:
Because the "opt" variable stores the option name (e.g., a, b, c), we can use a case statement to help process them:
The "case $opt in" statement uses the "opt" variable and then matches it against "a)", "b)", or "c)"—the first match wins. Case statements use pattern matching , and we could do a lot more with them if we wanted to.
Accepting options with values
Getting an option value is the last thing to learn—for example: "-a foo." First, we must tell getopts that an option accepts a value—add a colon after it in the option string. For example, "a:" tells getopts that "-a" accepts a value. It then becomes accessible via the "$OPTARG" variable.
Set a flag for optional debugging
Bugs are inevitable. Fortunately, Bash has a simple way to debug your script by printing all statements when they execute. We can also enable it optionally. Let's change our script to make that happen, using a "set -x" statement.
Now let's run the script:
You can see from the image that Bash prints each command it executes and most variables it evaluates.
You could enable it optionally via a flag:
Or you can enable it via an environment variable at the top of the script:
Then enable debug mode like this:
Doing it that way means it will print the option processing code too.
So that's it—a sensible help menu, CLI argument parsing, and debugging. Each of these will apply to nearly every script you write. In fact, they're so common, you could write a script to make other scripts, populating them with the concepts you've learned today. In programming, we call them snippets. I have a "create" and "edit" Bash script that does just that.
Bash is a much larger topic, but these three simple tips should set a solid foundation for you.
