BASH Debugging - Quick Tips | SUSE Communities

BASH Debugging – Quick Tips

Share
Share

Almost everyone knows (or should know) the basic options in bash debug.

-v Print shell input lines as they are read.
-x Print commands and their arguments as they are executed.

Sounds easy right?

See the difference, a practical example, a simple and silly script to demonstrate this:

billy@sles:~/lab> cat bashdebug.sh
#!/bin/bash
TODAY=`date +%F`
for number in 01 02 03; do echo "Hey, the number is: $number";done
echo "And today is $TODAY"
billy@sles:~/lab>

If we run it, we get:

billy@sles:~/lab> bash bashdebug.sh
Hey, the number is: 01
Hey, the number is: 02
Hey, the number is: 03
And today is 2013-04-19
billy@sles:~/lab>

Now let’s see how BASH it reads:

billy@sles:~/lab> bash -v bashdebug.sh
#!/bin/bash
TODAY=`date +%F`
date +%F
for number in 01 02 03; do echo "Hey, the number is: $number";done
Hey, the number is: 01
Hey, the number is: 02
Hey, the number is: 03
echo "And today is $TODAY"
And today is 2013-04-19
billy@sles:~/lab>

And how it runs or “expand

billy@sles:~/lab> bash -x bashdebug.sh
++ date +%F
+ TODAY='2013-04-19'
+ for number in 01 02 03
+ echo 'Hey, the number is: 01'
Hey, the number is: 01
+ for number in 01 02 03
+ echo 'Hey, the number is: 02'
Hey, the number is: 02
+ for number in 01 02 03
+ echo 'Hey, the number is: 03'
Hey, the number is: 03
+ echo 'And today is 2013-04-19'
And today is 2013-04-19
billy@sles:~/lab>

Notice that when we use this option the output has a prefix “+”

These options may seem trivial, but believe me: in big scripts it saves big headaches.

In addition to this we can use:

-u Exit the script after empty vars.

For example, let’s change the script a little bit:

billy@sles:~/lab> cat bashdebug.sh
#!/bin/bash
TODAY=`date +%F`
echo "Today is $TODAY"
for number in 01 02 03; do echo "Hey, the number is: $number";done
billy@sles:~/lab>

Run:

billy@sles:~/lab> bash bashdebug.sh
Today is 2013-04-19
Hey, the number is: 01
Hey, the number is: 02
Hey, the number is: 03
billy@sles:~/lab>

Works fine, but what happens if we don’t set the var $TODAY?

billy@sles:~/lab> cat bashdebug.sh
#!/bin/bash
#TODAY=`date +%F`
echo "Today is $TODAY"
for number in 01 02 03; do echo "Hey, the number is: $number";done
billy@sles:~/lab>
billy@sles:~/lab> bash bashdebug.sh
Today is
Hey, the number is: 01
Hey, the number is: 02
Hey, the number is: 03
billy@sles:~/lab>

Still works, not fine, but works, then how can we debug this? Of course, with -u

billy@sles:~/lab> bash -u bashdebug.sh
bashdebug.sh: line 3: TODAY: unbound variable
billy@sles:~/lab>

And we get the error! And again, one headache less.

And the next option:

-e Exit the script after simple errors.

And yes, example:

Bash does not stop at simple errors, with this option we force it to do so.

billy@sles:~/lab> cat bashdebug.sh
#!/bin/bash
source ./dontexist.conf
TODAY=`date +%F`
echo "Today is $TODAY"
for number in 01 02 03; do echo "Hey, the number is: $number";done
billy@sles:~/lab>

Run:

billy@sles:~/lab> bash bashdebug.sh
bashdebug.sh: line 2: ./dontexist.conf: No such file or directory
Today is 2013-04-19
Hey, the number is: 01
Hey, the number is: 02
Hey, the number is: 03
billy@sles:~/lab>

Of course it doesn’t exist, but the script is still running. Debug this? yes, with -e

billy@sles:~/lab> bash -e bashdebug.sh
bashdebug.sh: line 2: ./dontexist.conf: No such file or directory
billy@sles:~/lab>

This forces us to pay more attention to details.

Finally, we can use all these options together (-vxue), to invoke the script.

We can even use it selectively within the script using: set -/+, example:

billy@sles:~/lab> cat bashdebug.sh
#!/bin/bash
source ./dontexist.conf
set -u
TODAY=`date +%F`
echo "Today is $TODAY"
set +u
for number in 01 02 03; do echo "Hey, the number is: $number";done
billy@sles:~/lab>

Of course there are many more options and many more ways to debug bash, as the article title suggests, this is just a brief guide.

Happy Hacking!

Share
(Visited 1 times, 1 visits today)
Avatar photo
8,685 views