如何在调试期间以交互方式修改shell脚本?

时间:2017-08-03 12:01:32

标签: bash shell

在调试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脚本中处理这样一个问题的好方法?

谢谢

1 个答案:

答案 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=3return即可。在所有其他行上点击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
}

你的想象力是这里的极限。和语法。我会将您的解析器移动到一个单独的文件中,并根据需要提供它。

按顺序回答评论中的问题

  1. 注意我有echo $prev_cmd >> debug_log.bash。如果您之前未设置解析器,则prev_command在第一次调用解析器时将为空。由于shebang肯定从未调试过,因此不会出现在你的新文件中,因此将第一行转储到新文件是一个很好的初始选择 - 无论如何都需要它。无论你喜欢什么,你当然可以将它设置为空或一些评论。

  2. 当您进入调试功能时,将打开调试(根据定义)。为了防止在调试器中进行调试,我将其关闭。离开函数时,我需要重新激活它,以便继续调试。这就是为什么订单“反转”到文件 - 它会关闭您的初始激活,并在继续之前重新激活。

  3. 如果您想在sum=...之前停止调试,请先放置set +x - 这就是关闭调试的原因。就像我在解析器中所做的那样。

  4. 致谢:特别感谢Charles Duffy让代码更安全。而且更好。