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.)
With bash, you can use functrace
option in your script
set -o functrace
See manpage for bash
for other debugger options.
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
In ksh use typeset -ft function-name
to trace into a function
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/
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
精彩评论