在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
跟其他高级语言一样,Bash/Shell脚本也可以进行调试(Debug),学会这些调试技巧对编写和完善脚本有不小的帮助。 在本文中,您将学习一些有用的Bash/Shell脚本调试方法:
使用的软件要求和约定
使用传统技术即使代码错误很明显,调试代码也可能很棘手。程序员传统上利用诸如调试器和编辑器中的语法突出显示之类的工具来协助解决问题。编写Bash脚本没有什么不同。只需突出显示语法即可使您在编写代码时捕获错误。 一些编程语言附带了调试功能,例如gcc和gdb,它们使您可以逐步执行代码,设置断点,在执行时检查这些点处的所有内容的状态,等等。但是,Bash脚本通常不需要像这样的笨拙方法。 对于Shell脚本来说,仅对代码进行解释,而不是将其编译为二进制文件。 传统编程环境中使用了一些对复杂的Bash脚本有用的技术,例如使用断言。即在某个时间点明确声明条件或事物状态的方式,它们可以实现为一个简短的函数,该函数可以显示时间,行号等,或类似如下代码所示的东西:
如何使用Bash xtrace选项在编写Shell脚本时,编程逻辑往往会更短,并且通常包含在单个文件中。因此,我们可以使用一些内置调试选项来查看出了什么问题。要提到的第一个选项可能也是最有用的是-
这告诉Bash向我们展示每个语句在转化之后,执行之前的样子。稍后我们将看到一个实际的例子,但首先让我们对比一下
-x及与其 相反的-v ,-v显示每行之前的值,而不是之后的值。这两个选项可以组合使用,也就是同时使用-x 和-v,从而 看到变量替换发生前后的语句。图:在命令行中设置
x 和v 选项
如何使用其他Bash选项默认情况下,用于调试的Bash选项处于关闭状态,但是一旦使用set命令将其打开,它们将保持打开状态,直到显式关闭为止。如果您不确定启用了哪些选项,则可以检查
我们可以使用另一个有用的开关来帮助我们找到引用的变量,而无需设置任何值。这是 图:在命令行中设置
u 选项我们错误地为名为“level”的变量赋予了7这个值,然后试图回显名为“score”的变量,该未定义变量仅导致屏幕完全不打印任何内容。设置 我们可以在简短的Bash脚本中使用这些选项,以向我们提供调试信息,以识别那些不会触发Bash解释器反馈的问题。让我们来看几个例子。
图:使用
x 运行Bash脚本在上面的示例中,我们正常运行addpath脚本,但它根本不会修改我们的 看下一个示例,我们也没有从解释器得到任何错误指示。每行仅打印一个值,而不是两个。这是不会导致脚本停止执行的错误。使用
图:使用
u选项 从命令行运行脚本当我们处理更长和更复杂的脚本时,设置 幸运的是,我们可以通过将它们放置在脚本中来更精确地使用这些选项。我们可以通过将选项添加到shebang行中来设置选项,而不是通过命令行显式调用Bash shell。
这将为整个文件设置 对于更具针对性的方法,请仅用可选项包围可疑代码块。此方法可以通过分别使用带有正负的set关键字来实现。
图:在脚本中的代码块周围包装选项
我们仅围绕我们怀疑的代码块以减少输出,从而使我们的任务在调试过程中更加容易查看。请注意,我们仅对包含if-then-else语句的代码块打开选项,然后在可疑块的末尾关闭选项。如果我们无法缩小可疑区域的范围,或者想要在脚本执行过程中的各个时间点评估变量的状态,则可以在一个脚本中多次打开和关闭这些选项。如果我们希望在脚本执行的其余部分继续执行该选项,则无需关闭该选项。 我们还应该提到,有第三方编写的调试器,这些调试器使我们可以逐行逐步执行代码。您可能想研究这些工具,但是大多数人发现它们实际上并不是必需的。 正如经验丰富的程序员所建议的那样,如果您的代码太复杂而无法使用这些选项隔离可疑块,那么真正的问题是应该重构代码。过于复杂的代码意味着可能很难检测到错误,并且维护费时费力。 关于Bash调试选项,最后要提到的一件事是,还存在文件globing选项:
图:使用
f选项 关闭文件globing如何使用trap帮助调试如果脚本复杂,还有更多值得考虑的技术,包括使用前面提到的assert函数。另外一种方法是使用trap。 Shell脚本使我们可以捕获(trap)信号并在此时执行某些操作。 您可以在Bash脚本中使用的一个简单但有用的trap示例是捕获
图:使用trap捕获
EXIT 帮助调试脚本如您所见,仅将变量的当前值输出到屏幕对于显示逻辑失败的位置很有用。 与Bash脚本一起使用的另一个有用的trap是
图:使用trap
DEBUG 帮助调试脚本结论当您发现您的Bash脚本未按预期方式运行,并且难以确定问题的原因时,请考虑哪些信息将有助于您确定原因,然后使用最方便的调试工具来帮助您确定问题。 参考资料
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13