bash:调试选项和功能

时间:2011-09-14 11:00:04

标签: debugging bash function unix ksh

如果我跑

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。)

5 个答案:

答案 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