Ask Ubuntu is a question and answer site for Ubuntu users and developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is there any way to debug bash script without using echo and logging?

I'm talking about using breakpoints and stuff like that.

share|improve this question
up vote 14 down vote accepted

Yes there is Bash Debugger Project.

alt text

You can also use set -x and set-v at execution. HERE and HERE or HERE is some info on that.

good luck!

share|improve this answer

There several different ways, i.e.:

  • Run your script with the -x option

    bash -x
  • Add set -x in a new line at the beginning of your scriptfile after the Shebang #!/bin/bash and before the beginning of your script, set -v would display the shell input lines, set -x displays the executed commands and arguments

  • replace the shebang of your script file with #!/bin/bash -xv

share|improve this answer

shellcheck is the best in the town --

you can also integrate with vim, here is the git repo --

share|improve this answer

To the tune of what NES is saying there are set flags in bash to allow for debugging.

the set -x flag may be set and unset either from the terminal, or from withing your script. using + or -

ls -l $1
set -x      # start debugging here
wc -l $1
set +x      # stop debugging here
file $1
set -v      # start verbose output
w | more    
echo ""
echo -n "Number of users: "
set +v      # end verbose output
who | wc -l

here is what the set commands do:

set -f Disable file name generation using metacharacters.

set -v Prints (verbose) shell input lines as they are read.

set -x Print command traces before executing command.

set actually has many features, but woefully no man page as it is a shell built in tool The manual for set is here

there are numerous command line tools which could help you gain details about your program like:

stat #display file or file system status

file #determine a file type.

hexdump #filter which displays the specified files in a variety of formats

nohup #Run a script that wont hang

and numerous others. I was trying to think of the command that shows hidden characters, but i cant do it right now. Hexdump will do it but there is a better one.

The key command "ctrl \" will cause a running program or script to core dump. Then you could analyze the coredump. I would probably use gdb to analyze a coredump, but many programs exist for that.

The bash shell has some nifty options for debugging too. options "--debugger", "-v" verbose, "--dump-strings" and other nifty options to assist you. Check them out using $man bash.

The trap command (shell built in) could be very helpful for you. trap says if your program exits unexpectedly, execute something. You read about trap, and other handy Bash Shell built ins here:

Speaking generally for the moment, debugging is a huge topic in any language. Some other topics that can be handy for debugging in any programing language include, shell redirection and, signal processing.

Finally, I realize the example I used is trivial, but that some shell scripts can be hundreds of lines. In those situations, I like to either insert comments tags and block out code I suspect is faulty, or Alternatively, insert an exit command, and try to isolate the functional code from the broken code, using a divide and conquer technique.

share|improve this answer

You can use this small function to drop into "console":

function debug
    echo "#############|  Entering DEBUG mode  |####################";
    while [[ $CMD != "exit" ]]; do
        read -p "> " CMD
        case $CMD in
            vars ) ( set -o posix ; set );;
            exit ) ;;
            * ) eval $CMD;;
    echo "#############|  End of DEBUG mode |####################";

Then, inside your script (EXAMPLE):

for FILE in *; do
   if [[ $FILE == "strange_case.txt" ]]; then
       # break the code here to analyze:

It will accept any command, keeping local variables intact. To exit "debug" mode, type "exit" (it won't exit the script) and it will continue with the code. If you use "debug" inside a loop, it will stop each time. You can wrap it inside an "if" (as in the example above), or create a "watch" function:

function debug_watch
    if [[ $1 == $2 ]]; then

# And Use it:

debug_watch $FILE "strange_case.txt"

I also added "vars" command which will dump all the available variables and their values. You can add your own customized commands as well.

I did the code in few minutes so use it under your own risk. Be aware that in debug mode any command can be executed, so it poses a security risk if you leave it in a production script.

share|improve this answer
Avoid using uppercase variable names. Your risk overriding special shell variables and environment variables. Also, make sure you quote parameter expansions when they're used as arguments, to avoid word-splitting and pathname expansion occuring on the result. e.g. * ) eval "$cmd" ;; and debug_watch "$file" strange_case.txt. – geirha May 15 '15 at 7:44

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.