是否有办法暂停shell脚本的执行以检查环境的状态或执行随机命令?
alias
结合eval
提供了调用上下文中断点的基本功能:
#!/bin/bash
shopt -s expand_aliases
alias breakpoint='
while read -p"Debugging(Ctrl-d to exit)> " debugging_line
do
eval "$debugging_line"
done'
f(){
local var=1
breakpoint
echo $'n'"After breakpoint, var=$var"
}
f
在断点处,可以输入
echo $var
紧随其后var=2
然后按Ctrl-d退出断点。
由于while循环中有eval
,请谨慎使用
Bash或shell脚本不具有像Java、Python等其他编程语言那样的调试功能。
我们可以将echo "VAR_NAME=$VAR_NAME"
命令放在我们想要记录变量值的代码中。
function BREAKPOINT() {
BREAKPOINT_NAME=$1
echo "Enter breakpoint $BREAKPOINT_NAME"
set +e
/bin/bash
BREAKPOINT_EXIT_CODE=$?
set -e
if [[ $BREAKPOINT_EXIT_CODE -eq 0 ]]; then
echo "Continue after breakpoint $BREAKPOINT_NAME"
else
echo "Terminate after breakpoint $BREAKPOINT_NAME"
exit $BREAKPOINT_EXIT_CODE
fi
}
export -f BREAKPOINT
,然后,在我们需要中断的代码行,我们像这样调用这个函数:
# some shell script here
BREAKPOINT MyBreakPoint
# and some other shell script here
那么BREAKPOINT函数将记录一些输出,然后启动/bin/bash
,我们可以运行任何echo
或其他我们想要的shell命令。当我们想要继续运行shell脚本的其余部分时(释放断点),我们只需要执行exit
命令。如果我们需要终止脚本执行,我们可以运行exit 1
命令。
存在像bash-debug这样的解决方案。对我来说,穷人的解决方案是交互式外壳。通过添加三行代码,您可以内省和更改变量,如下所示:
让我们假设,您有脚本test.bash
A=FOO
export B=BAR
echo $A
echo $B
$ test.bash
FOO
BAR
如果您在第3行添加交互式shell,您可以查看并检查之前导出的变量:
A=FOO
export B=BAR
bash -c "$SHELL"
echo $A
echo $B
$ test.bash
$ echo $A
$ echo $B
BAR
$ exit
FOO
BAR
如果你想在你的交互式shell中看到所有的变量,你必须在你的脚本的序言中添加set -a
,这样所有的变量和函数都被导出:
set -a
A=FOO
export B=BAR
bash -c "$SHELL"
echo $A
echo $B
$ test.bash
$ echo $A
FOO
$ echo $B
BAR
$ exit
FOO
BAR
注意,您不能更改交互式shell中的变量。对我来说,唯一的解决方案是提供一个额外的变量脚本,它将在交互式shell
之后提供。set -a
A=FOO
export B=BAR
bash -c "$SHELL"
source /tmp/var
echo $A
echo $B
$ test.bash
$ echo "export A=alice" > /tmp/var
$ echo "export B=bob" >> /tmp/var
$ exit
alice
bob