9

If I run

bash -x myscript.sh

I'll get debugging output.

But if I have a function in myscript.sh, the code in the function is immune to -x option. It writes to output only the name of the function.

How to obtain debugging output for functions in bash scripts?

Update:

Following the ztank1013's response, I just realized that I used ksh, not bash. Seems bash has by default the functrace option enabled in my system(thanks bash-o-logist)

I am satisfied, but for the community I maintain the question open for ksh.

For script:

#!/bin/ksh

a=2
testering(){
        a=3
        if [ $a -eq 3 ]; then
                echo lili
        fi
}
if [ $a -eq 2 ]; then
        echo mimi
fi

testering
exit

output of ksh -x ./testdebug.sh is:

+ a=2
+ [ 2 -eq 2 ]
+ echo mimi
mimi
+ testering
lili
+ exit

So, for ksh, what's the trick?

(If no answer will come, the 'correct' will go to bash-o-logist.)

0

5 Answers 5

13

With bash, you can use functrace option in your script

set -o functrace

See manpage for bash for other debugger options.

Sign up to request clarification or add additional context in comments.

1 Comment

Can you please elaborate what enabling functrace does.
4

I cannot reproduce your problem, in fact given my test script (debug.sh):

[root ~]# cat debug.sh
#!/bin/bash
fun01 () {
echo "BUT HERE I am inside the function fun01() body"
}
echo "HERE I am outside the function fun01() body!"
sleep 2
fun01
exit

I run it with debug option turned off:

[root ~]# ./debug.sh
HERE I am outside the function fun01() body!
BUT HERE I am inside the function fun01() body

and turned on (bash -x ...):

[root ~]# bash -x ./debug.sh
+ echo 'HERE I am outside the function fun01() body!'
HERE I am outside the function fun01() body!
+ sleep 2
+ fun01
+ echo 'BUT HERE I am inside the function fun01() body'
BUT HERE I am inside the function fun01() body
+ exit

As far as I can see the line executed inside the fun01() function is showed with a starting + which is the debugger in action.

@bash-o-logist Even if I add variable or if/then/else conditional constructs I still get all the debug info:

[root@ ~]# cat debug-new.sh
#!/bin/bash
fun01 () {
INSIDEVAR='Never really use this one'
echo "BUT HERE I am inside the function fun01() body"
if [ true ] ; then echo 'this is going to be printed always!' ; fi
}
echo "HERE I am outside the function fun01() body!"
sleep 2
fun01
exit

Executing again:

[root@ ~]# bash -x debug-new.sh
+ echo 'HERE I am outside the function fun01() body!'
HERE I am outside the function fun01() body!
+ sleep 2
+ fun01
+ INSIDEVAR='Never really use this one'
+ echo 'BUT HERE I am inside the function fun01() body'
BUT HERE I am inside the function fun01() body
+ '[' true ']'
+ echo 'this is going to be printed always!'
this is going to be printed always!
+ exit

1 Comment

you cannot just echo some statements inside the functions. Try declaring variables and using if/else inside the functions.
2

In ksh use typeset -ft function-name to trace into a function

1 Comment

@FlorinGhita inside the script, replacing function-name with name of the function being debugged.
0

I had similar question and I ended in writing my own debbuger for Bash. Try it! ... I hope it will help you https://sourceforge.net/projects/bashdebugingbash/

1 Comment

screenshot looks promising but does not work ``` 1 /usr/share/bdb $ pwd /usr/share/bdb 1 /usr/share/bdb $ ./bdb.sh + for bdbINC in inc/bdb.lang inc/bdb.vars inc/bdb.lib + INCFICH=/usr/share/bdb/inc/bdb.lang + typeset -u INCUPR=inc/bdblang + INCFLAG=INC/BDBLANG_INCLUDE ./bdb.sh: line 29: INC/BDBLANG_INCLUDE: bad substitution + exit ``` and my spanish is too lousy to understand your code
0

This is how I force debugging to turn on or off inside function blocks in bash scripts.

If debugging is on when the script starts, it is turned on inside function blocks. Each function block has a start and end message for easier tracing.

This is for runtime debugging. Best to redirect the output to a log file for analysis later, e.g.

bash -x ./runtime_bash_debugging>log 2>&1
-- or --
./runtime_bash_debugging>log 2>&1

Example output with debugging on at the start

$ bash -x ./runtime_bash_debugging.sh
+ run_me_first
+ FN_NAME=run_me_first
+ MSG='BEGINNING OF: run_me_first'
+ test '' = on
++ date
+ echo 'I run first, it'\''s Sat Oct 27 19:11:06 MDT 2018'
I run first, it's Sat Oct 27 19:11:06 MDT 2018
+ MSG='END OF: run_me_first'
+ test '' = on
+ run_me_second
+ FN_NAME=run_me_second
+ MSG='BEGINNING OF: run_me_second'
+ test '' = on
+ echo 'I run second, my PID is 5744'
I run second, my PID is 5744
+ MSG='END OF: run_me_second'
+ test '' = on
+ echo Goodbye
Goodbye
+ exit

Example output with debugging off at the start

$ ./runtime_bash_debugging.sh
I run first, it's Sat Oct 27 19:11:09 MDT 2018
I run second, the PID is 4784
Goodbye

THE SCRIPT

#!/bin/bash

# runtime bash debugging

fn_check_xtrace() {
    XTRACE_BEGIN_STATE=`set -o|awk '$1=="xtrace"{print $2}'`
    echo "${XTRACE_BEGIN_STATE}"
}


function run_me_first() {
    FN_NAME="run_me_first"
    MSG="BEGINNING OF: ${FN_NAME}"

    if test "${XTRACE_BEGIN_STATE}" = "on"
    then
    set -x
    fi

    echo "I run first, it's `date`"

    MSG="END OF: ${FN_NAME}"

    if test "${XTRACE_BEGIN_STATE}" = "on"
    then
    set -x
    fi
}


function run_me_second() {
    FN_NAME="run_me_second"
    MSG="BEGINNING OF: ${FN_NAME}"

    if test "${XTRACE_BEGIN_STATE}" = "on"
    then
    set -x
    fi

    echo "I run second, the PID is $$"

    MSG="END OF: ${FN_NAME}"

    if test "${XTRACE_BEGIN_STATE}" = "on"
    then
    set -x
    fi
}

run_me_first

run_me_second

echo "Goodbye"

exit

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.