[one-liner]: Debugging Bash Scripts

Background

From time to time it’s useful if you can turn up the debugging messages that come from Bash, when working out either interactive or shell script problems. Here are 2 methods that can help in getting down to the details.

Solution

There are essentially 2 methods.

Method #1: -x method

When writing a shell script you’ll sometimes want to turn on line by line debugging. There’s basically 2 ways to to this.

Before we get started, suppose we have this sample script, myscript.bash:

1
2
3
4
#!/bin/bash
 
echo "hi"
echo "bye"

First you can run your script like so:

1
2
3
4
5
% bash -x myscript.bash
+ echo hi
hi
+ echo bye
bye

As an alternative you can add the following line, set -x to the top of our shell script to enable debugging as well:

1
2
3
4
5
#!/bin/bash
 
set -x
echo "hi"
echo "bye"
1
2
3
4
5
% ./myscript.bash
+ echo hi
hi
+ echo bye
bye
Method #2: env SHELLOPTS=xtrace …

This approach sets the env. variable SHELLOPTS=xtrace which has the same effect as using bash -x.

For example:

1
2
3
4
5
% env SHELLOPTS=xtrace ./myscript.bash 
+ echo hi
hi
+ echo bye
bye

You can also use this technique to debug your bash environment (think .bashrc and .bash_profile) like so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
% env SHELLOPTS=xtrace bash
...
...
+++++ line='complete -f -X
'\''!*.@(zip|[ejw]ar|exe|pk3|wsz|zargo|xpi|sxw|o[tx]t|od[fgpst]|epub|apk)'\''
unzip zipinfo'
+++++ line=' unzip zipinfo'
+++++ list=("${list[@]}" $line)
+++++ read line
+++++ '[' 'complete -f -X '\''*.Z'\'' compress znew' '!=' 'complete -f
-X '\''*.Z'\'' compress znew' ']'
+++++ line='complete -f -X '\''*.Z'\'' compress znew'
+++++ line='complete -f -X '\''*.Z'\'' compress znew'
+++++ line=' compress znew'
+++++ list=("${list[@]}" $line)
+++++ read line
+++++ '[' ' zcmp, zdiff, z*grep, zless, zmore intentionally not here,
see Debian: #455510' '!=' '# zcmp, zdiff, z*grep, zless, zmore
intentionally not here, see Debian: #455510' ']'
...
...

Here you can see every command getting executed from the system and user’s .bashrc and .bash_profile as bash starts up.

NOTE: For further details regarding my one-liner blog posts, check out my one-liner style guide primer.

This entry was posted in bash, one-liner, script, shell, Syndicated, tips & tricks. Bookmark the permalink.

Comments are closed.