Sometimes when I have a problem with a bash script I want the ability to run each line of the script one by one to see what is wrong. There is a debugger called bashdb that can be used in this way. It behaves similarly to gdb (used for debugging C and C++ programs) and pdb (used for debugging Python programs).
First you need to determine what version of bash you are running, since you need to use a corresponding version of bashdb:
# bash --version GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
This version of bash is 5.1.16, so we need a bashdb version 5.1.x. Let’s download it:
NOTE: The following commands are written for an Ubuntu- or Debian-based Linux distribution. Also, you may need to prefix some commands with
sudo to avoid permission errors.
# apt-get update # apt-get install git -y # git clone https://git.code.sf.net/p/bashdb/code bashdb-code # cd bashdb-code/ # git checkout bash-5.1
For bashdb >= 5.1.x, you’ll need to build the
# apt-get update # apt-get install autoconf -y # to run autogen.sh # apt-get install binutils -y # to install "strings" tool, for autogen.sh # apt-get install make -y # to install "make" tool # apt-get install texinfo -y # to install "makeinfo" tool, for make # ./autogen.sh
You should now have a
bashdb file in the current directory:
# ls | grep bashdb bashdb bashdb-main.inc bashdb-main.inc.in bashdb-part2.sh bashdb-trace bashdb-trace.in bashdb.in
(Optional) If you have root permissions, you can install bashdb:
# make install
Let’s create an example script to debug:
# cat << EOF > /tmp/hello.sh echo 1 echo 2 echo 3 echo 4 EOF
If you did install bashdb in the step above, start the debugger on a Bash script at
# bash --debugger /tmp/hello.sh ... (/tmp/hello.sh:1): 1: echo 1 bashdb<0>
If you did not install bashdb, you can run the debugger by calling the bashdb script manually:
# bash ./bashdb /tmp/hello.sh ... (/tmp/hello.sh:1): 1: echo 1 bashdb<0>
See all debugger commands using
bashdb<0> help Available commands: ------------------- action condition edit frame load run source unalias alias continue enable handle next search step undisplay backtrace debug eval help print set step+ untrace break delete examine history pwd shell step- up clear disable export info quit show tbreak watch commands display file kill return signal trace watche complete down finish list reverse skip tty Readline command line editing (emacs/vi mode) is available. Type "help" followed by command name for full documentation. bashdb<1>
See where you are in the script using
bashdb<1> list 1: => echo 1 2: echo 2 3: echo 3 4: echo 4 5: bashdb<2>
You can step over the current line using
bashdb<3> next 1 (/tmp/hello.sh:2): 2: echo 2 bashdb<4> list 1: echo 1 2: => echo 2 3: echo 3 4: echo 4 5: bashdb<5>
You can step into the current line using
s. This is useful to enter into a function call or a line that uses
source to call another script:
bashdb<6> step 2 (/tmp/hello.sh:3): 3: echo 3 bashdb<7> list 1: echo 1 2: echo 2 3: => echo 3 4: echo 4 5: bashdb<8>
You can step out of the current function with
Other common commands include:
eval STATEMENT- Run a statement.
print EXPR- Print an expression, such as a variable.
break- Set a breakpoint.
break 3(set breakpoint on line 3)
break /tmp/hello.sh:4(set breakpoint on line 4 of file
c- Step continuously until a breakpoint is hit or the script ends.
exit- Stop the script and exit the debugger.