bash脚本排错技巧
下面会给出一些实用的排错小技巧,对于快速定位问题脚本会有非常大的帮助。
面是主要的 Shell 脚本调试选项:
-v
(verbose 的简称) - 告诉 Shell 读取脚本时显示所有行,激活详细模式。-n
(noexec 或 no ecxecution 简称) - 指示 Shell 读取所有命令然而不执行它们,这个选项激活语法检查模式。-x
(xtrace 或 execution trace 简称) - 告诉 Shell 在终端显示所有执行的命令和它们的参数。 这个选项是启用 Shell 跟踪模式。
使用 Shell 内置命令 set
第三个方法是使用内置命令 set
去调试一个给定的 Shell 脚本部分,如一个函数。这个机制是重要的,因为它让我们可以去调试任何一段 Shell 脚本。
我们可以如下使用 set
命令打开调试模式,其中选项是之前提到的所有调试选项。
$ set 选项
启用调试模式:
$ set -选项
禁用调试模式:
$ set +选项
此外,如果我们在 Shell 脚本不同部分启用了几个调试模式,我们可以一次禁用所有调试模式,如下:
$ set -
一、使用-x跟踪脚本执行过程
使用-x跟踪脚本执行过程,这是非常重要的一种排错方式。可以使用bash -x执行脚本,也可以通过为脚本中第一行解释器添加-x选项来实现相同功能的跟踪功能。如果输出结果以双加号开头(++)则表示命令是在子Shell中执行的。
上面是一个错误的脚本示例,你能找出问题在哪里吗?在执行的时候脚本不会报错,但是最终并不会创建我们需要的jacob、tintin和demo这三个用户,如果不仔细多看几遍脚本,有时候发现问题还是比较困难的。对于这样的脚本我们就可以使用-x跟踪脚本执行过程,可以非常快速地发现问题所在!
通过分析屏幕输出的信息,我们可以很清晰地看到整个脚本的执行流程,首先进行变量的定义赋值,其次通过for循环创建三个账户,但是在执行循环中的useradd命令时,变量替换后会发现i的值不对,我们需要让i调用的是user1、user2和user3的变量值,而实际执行时,变量i被直接替换为了user1、user2和user3,找到问题了,调用变量user1、user和user3时没有添加$符号!修改为正确的脚本效果如下:
添加一些额外的辅助命令,也能帮助我们在排错的过程中定位错误原因。例如,增加额外的echo命令就是常见的做法,当我们不太确定错误时,可以在脚本中放置一个echo显示脚本的执行结果,辅助我们分析出现问题的原因。
可以看出上面脚本的问题吗?对,进入循环后没有使用命令修改变量i的值,结果导致i始终为1,进而造成了一个无限死循环。像这样的脚本我们就可以通过在循环中添加echo来查看变量的值。
最后一条排错小技巧是将脚本中的单个命令复制到命令行执行。有时候我们并不太确定脚本中的命令格式或逻辑是否正确,这时可以单独将某些命令复制到命令行执行一遍以检查错误,这种方法也是在工作中经常用到的排错方式。
二、 当运行失败时使脚本退出
有时即使某些命令运行失败,bash 可能继续去执行脚本,这样就影响到脚本的其余部分(会最终导致逻辑错误)。用下面的行的方式在遇到命令失败时来退出脚本执行:
# 如果命令运行失败让脚本退出执行
set -o errexit
# 或
set -e
三、 当 Bash 用未声明变量时使脚本退出
Bash 也可能会使用能导致起逻辑错误的未声明的变量。因此用下面行的方式去通知 bash 当它尝试去用一个未声明变量时就退出脚本执行:
# 若有用未设置的变量即让脚本退出执行
set -o nounset
# 或
set -u