如果我跑
bash -x myscript.sh
我会得到调试输出。
但如果我在myscript.sh
中有一个函数,则函数中的代码不受-x选项的影响。它只写输出函数的名称。
如何获取bash脚本中函数的调试输出?
更新
在ztank1013的回复之后,我才意识到我使用的是ksh,而不是bash。似乎bash默认情况下在我的系统中启用了functrace选项(感谢bash-o-logist)
我很满意,但对于社区,我维持ksh的问题。
对于剧本:
#!/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
ksh -x ./testdebug.sh
的输出是:
+ a=2
+ [ 2 -eq 2 ]
+ echo mimi
mimi
+ testering
lili
+ exit
那么,对于ksh来说,有什么诀窍呢?
(如果没有答案,'正确'将转到bash-o-logist。)
答案 0 :(得分:9)
使用bash,您可以在脚本中使用functrace
选项
set -o functrace
有关其他调试器选项,请参阅bash
的联机帮助页。
答案 1 :(得分:4)
我无法重现您的问题,实际上是给出了我的测试脚本(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
我在关闭调试选项的情况下运行它:
[root ~]# ./debug.sh
HERE I am outside the function fun01() body!
BUT HERE I am inside the function fun01() body
然后打开(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
据我所知,在fun01()函数中执行的行显示为一个起始+,它是运行中的调试器。
@bash-o-logist即使我添加变量或if / then / else条件结构,我仍然可以获得所有调试信息:
[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
再次执行:
[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
答案 2 :(得分:2)
在ksh中使用typeset -ft function-name
来追踪函数
答案 3 :(得分:0)
我有类似的问题,最后我为Bash编写了自己的调试器。试试吧! ......我希望它会帮助你https://sourceforge.net/projects/bashdebugingbash/
答案 4 :(得分:0)
这是我强制调试在bash脚本中的功能块内打开或关闭的方式。
如果在脚本启动时打开调试,则在功能块内部将其打开。每个功能块都有一个开始和结束消息,以便于跟踪。
这是用于运行时调试。最好将输出重定向到日志文件中,以便以后进行分析,例如
bash -x ./runtime_bash_debugging>log 2>&1
-- or --
./runtime_bash_debugging>log 2>&1
示例输出并在开始时进行调试
$ 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
示例输出,并在开始时关闭调试
$ ./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
脚本
#!/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