bash:调试选项和函数

发布于 2024-12-04 15:48:33 字数 770 浏览 2 评论 0原文

如果我运行

bash -x myscript.sh

我会得到调试输出。

但是,如果我在 myscript.sh 中有一个函数,则该函数中的代码不受 -x 选项的影响。它仅写入输出函数的名称。

如何获取 bash 脚本中函数的调试输出?

更新:

根据ztank1013的回复,我刚刚意识到我使用的是ksh,而不是bash。看来 bash 默认情况下在我的系统中启用了 functrace 选项(感谢 bash-o-logger),

我很满意,但对于社区来说,我仍然对 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。)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

原来分手还会想你 2024-12-11 15:48:33

使用 bash,您可以在脚本中使用 functrace 选项,

set -o functrace

请参阅 bash 的联机帮助页了解其他调试器选项。

With bash, you can use functrace option in your script

set -o functrace

See manpage for bash for other debugger options.

薆情海 2024-12-11 15:48:33

我无法重现您的问题,事实上给定我的测试脚本(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-logger即使我添加变量或 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

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
川水往事 2024-12-11 15:48:33

在 ksh 中,使用 typeset -ft function-name 跟踪函数

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

嘿嘿嘿 2024-12-11 15:48:33

我有类似的问题,最后我为 Bash 编写了自己的调试器。试试吧! ...我希望它会对您有所帮助 https://sourceforge.net/projects/bashdebugingbash/

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/

2024-12-11 15:48:33

这就是我强制调试在 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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文