在调试bash shell脚本时,我发现我在代码的某些部分中犯了一个错误。这个错误可以是变量名,变量值或一般代码行。
运行调试模式时是否可以更正?或者唯一的选择是退出调试模式,纠正错误并重新运行调试过程?如果有这样一种纠正错误的选择,那将是非常有帮助的。存在。特别是对于需要较长运行时间的脚本而言,您必须多次重复整个运行过程(如果有很多错误)。
例如:
#!/bin/bash
set -x # debugging
trap read debug
a="1" # wrong value, should be 2
b="5"
sum=$(bc <<< "$a + $b")
set +x
上面的脚本有一个陷阱,一次执行一行代码,并在按Enter键后继续到下一行。 在调试期间假设我意识到a = 1但应该是其他东西让我们说a = 2。下一个命令b = 5,由于陷阱而没有执行,所以我想在a = 1下面插入一个= 2然后继续进行继续调试。
类似下面的代码:
#!/bin/bash
set -x # debugging
trap read debug
a="1" # wrong value, should be 2
a="2" # <-This is the value that a should have
b="5"
sum=$(bc <<< "$a + $b")
set +x
这种方法不起作用,我猜是因为整个脚本只在运行开始时调用。什么是在shell脚本中处理这样一个问题的好方法?
谢谢
答案 0 :(得分:2)
稍微充实你的解析器:
#!/bin/bash
function parser {
IFS= read -r input
printf "Going to do: >%s\n" $input
eval "$input"
}
set -x # debugging
trap "parser" debug
a="1"
b="5"
sum=$(bc <<< "$a + $b")
set +x
这当然只适用于一个衬垫,但应该让你开始。当您看到调试在a=1
上时(您将在屏幕上看到),您只需输入a=3
和return
即可。在所有其他行上点击return
- 您会在sum
看到效果。
请注意,在此方法中(在调试中看到行后覆盖),您始终运行 AFTER 错误命令,因为那是调试器输出的时间。如果要在运行之前查看命令
echo $BASH_COMMAND
解析器中的。当然,在a=10
运行之前运行a=1
会产生相反的效果。
例如,改进可能是在解析时关闭调试,如果没有收到输入则跳过echo:
function parser {
set +x
IFS= read -r input
if ! [ -z "$input" ]; then
printf "Going to do: >%s\n" $input
eval "$input"
fi
set -x
}
请注意,这不会修改脚本本身。要修改脚本本身,您还需要添加sed
命令以实际修改脚本,或者可能将每行回显到新文件,如果收到则替换为调试中的新输入 - 这是更安全的选择。这可以这样做(注意解析器在行已经运行之后运行,因此我们总是输出上一个命令,并在需要时覆盖它):
set prev_cmd="#!/bin/bash"
function parser {
set +x
IFS= read -r input
if ! [ -z "$input" ]; then
printf "Going to do: >%s\n" $input
eval "$input"
prev_cmd=$input
fi
echo $prev_cmd >> debug_log.bash
prev_cmd=$BASH_COMMAND
set -x
}
你的想象力是这里的极限。和语法。我会将您的解析器移动到一个单独的文件中,并根据需要提供它。
按顺序回答评论中的问题
注意我有echo $prev_cmd >> debug_log.bash
。如果您之前未设置解析器,则prev_command
在第一次调用解析器时将为空。由于shebang肯定从未调试过,因此不会出现在你的新文件中,因此将第一行转储到新文件是一个很好的初始选择 - 无论如何都需要它。无论你喜欢什么,你当然可以将它设置为空或一些评论。
当您进入调试功能时,将打开调试(根据定义)。为了防止在调试器中进行调试,我将其关闭。离开函数时,我需要重新激活它,以便继续调试。这就是为什么订单“反转”到文件 - 它会关闭您的初始激活,并在继续之前重新激活。
如果您想在sum=...
之前停止调试,请先放置set +x
- 这就是关闭调试的原因。就像我在解析器中所做的那样。
致谢:特别感谢Charles Duffy让代码更安全。而且更好。