Bash scripts have you in a funk? Find out how to start the process of debugging those scripts, with the help of tools that work seamlessly with your code.
For many Linux administrators, bash scripts are a must-use. These handy scripts help make Linux one of the most flexible operating systems on the planet. There's very little you cannot do with a well-written script. But what happens when you've carefully constructed that script, only to find it doesn't run as planned? Something is amiss. If the script is lengthy and complicated, you might have a heck of a time tracking down the issue(s).
Fortunately, there are plenty of tools available to help you debug your bash scripts. One such tool is set x. This particular debugging tool allows you to mark in a script where you want to focus your debugging efforts. With set x you can either debug an entire script, a section of a script, or a single line. A second handy tool allows you to log output of script to a file. This comes in quite handy, especially when your script is longer than usual (or you want to debut the output later).
SEE: System update policy template download (Tech Pro Research)
Let's take a look at how these two tools are used in a simple bash script.
What you need
The only thing you need for this is a Linux distribution. Most every distribution will contain the necessary tools, however, the distribution must include bash version 5.0 or better. You can find out which version of bash your distribution includes with the command bash —version. Because we're working with the command line, it doesn't matter if you use a desktop or a server distribution.
The basic script we'll use for this test is:
#!/bin/bash var="Hello World" # print it echo "$var" # Another way of printing it printf "%s\n" "$var" echo "Your home is: $HOME"
That's a fairly straightforward script. Create a new file with the command nano hello.world with the above contents. Save and close the file. Give the new file executable permissions with the command:
chmod u+x hello.world
Now execute the script with the command:
You should see exactly the output you expect (Figure A).
Of course, there's nothing wrong with this script, but it makes for an excellent example.
The modified script
Now we're going to modify the script, to include our debugging tools. The first is the logging entry. Under #!/bin/bash, add the following:
exec 5> debug_output.txt BASH_XTRACEFD="5" PS4='$LINENO: '
The first line names our debugging file, debug_output.txt. The second line tells bash where to write its xtrace information (which will be declared with set x). Finally, the third line will print out line numbers, to make our debugging even easier.
Next, we need to use set x to indicate which code we want to debug. Let's say the echo $HOME section of the script is working as expected, whereas the echo $var isn't. Let's encase that section with set x so we can only debug that portion of the script. We declare the beginning of the section to be debugged with set -x and the end with set +x. So the new section of code will look like:
set -x var="Hello World" # print it echo "$var" # Another way of printing it printf "%s\n" "$var" set +x
Save and close that file.
Now run the sh ./hello.world command. This time around, the output is quite different (Figure B).
As you see, every line of command begins with a : character, and the output generated by the lines of code immediately follows and does not include the : character. This makes it far easier to debug what is going on.
If you don't find any errors in the code that you marked with set -x and set +x, move those lines to another section and run the command again.
Debugging via log file
If you're dealing with a bash script that is too long for standard output, you'll want to take a look at that debugging log file we declared. However, you'll find that file empty. Why? Because we've run the script with the help of the sh shell, and the sh shell isn't compatible with the BASH_XTRACEFD command. Instead of running the script with sh ./hello.world, simply issue the command ./hello.world. This will use bash, instead of sh, and our debugging output can then be viewed (Figure C) with the command:
Because we've written our script in such a way, we can:
- Run the script with sh ./hello.world to see our debugging information sent to standard output (which means it is printed in the terminal window after you run the command).
- Run the script with ./hello.world to have our debugging information written to the debug_output.text file.
You might also notice, if you run the script with the command ./hello_world, the debugging information is not sent to standard output, and will look exactly as it did in Figure A.
And this is a very simple way to begin the process of debugging your bash scripts. To many, this will seem like baby steps, but once you get the hang of using these tools, you'll find them an invaluable means to debugging those scripts.
- How to create a bash script for starting VirtualBox VMs (TechRepublic)
- How to use the curl command for uploading and downloading files without user interaction (TechRepublic)
- How to run Linux commands simultaneously with GNU Parallel (TechRepublic)
- How to use ssh-agent to make working with secure shell more efficient (TechRepublic)
- Google open-sources project for sandboxing C/C++ libraries on Linux (ZDNet)
- The 10 most important iPhone apps of all time (Download.com)
- It takes work to keep your data private online. These apps can help (CNET)
- Programming languages and developer career resources coverage (TechRepublic on Flipboard)