在shell脚本调试系列中,本文将讲解shell脚本调试的第三种模式,shell跟踪,并通过一些例子来演示其工作原理和使用方法。本系列的前几部分阐明了另外两种shell脚本调试模式:详细模式和语法检查模式,并通过易于理解的示例展示了如何在这些模式下启用shell脚本调试。如何在Linux中为Shell脚本启用调试模式如何在Shell脚本中执行语法检查调试模式shell跟踪简单地意味着跟踪shell脚本中命令的执行。要打开shell跟踪,请使用-x调试选项。这会导致shell在终端上显示所有已执行的命令及其参数。我们将使用下面的sys_info.shshell脚本,它会简要地打印出您的系统日期和时间、登录的用户数量以及系统的正常运行时间。但是,该脚本包含我们需要查找和更正的语法错误。#!/bin/bash#scripttoprintbriefsysteminfoROOT_ID="0"DATE=`date`NO_USERS=`who|wc-l`UPTIME=`uptime`check_root(){if["$UID"-ne"$ROOT_ID"];thenecho"Youarenotallowedtoexecutethisprogram!"exit1;}print_sys_info(){echo"SystemTime:$DATE"echo"Numberofusers:$NO_USERS"echo"SystemUptime:$UPTIME}check_rootprint_sys_infoexit0保存文件并执行脚本。脚本只能用root运行用户,所以使用如下sudo命令运行:$chmod+xsys_info.sh$sudobash-xsys_info.shshellTrace-显示脚本中的错误从上面的输出我们可以观察到首先执行命令然后使用它的输出作为变量的值,比如先执行date,输出为变量DATE的值。我们可以执行语法检查以仅显示其中的语法错误,如下所示:$sudobash-nsys_info.sh脚本中的语法检查如果我们检查此shell脚本,我们会发现if语句缺少用于封闭条件的fi关键字。所以让我们添加一点,新脚本应该是这样的:#!/bin/bash#scripttoprintbriefsysteminfoROOT_ID="0"DATE=`date`NO_USERS=`who|wc-l`UPTIME=`uptime`check_root(){if["$UID"-ne"$ROOT_ID"];thenecho"Youarenotallowedtoexecutethisprogram!"exit1;fi}print_sys_info(){echo"SystemTime:$DATE"echo"Numberofusers:$NO_USERS"echo"SystemUptime:$UPTIME}check_rootprint_sys_infoexit0保存文件再次以root身份执行,同时做语法检查:$sudobash-nsys_info.sh在shell脚本中执行语法检查以上语法检查操作的结果还是显示第21行有错误脚本。所以,我们仍然需要修正一些语法。再次分析脚本,你会发现第21行的错误是由于print_sys_info函数中最后一个echo命令没有结束双引号"。我们将在echo命令中添加结束双引号并保存文件。修改后的脚本如下:#!/bin/bash#scripttoprintbriefsysteminfoROOT_ID="0"DATE=`date`NO_USERS=`who|wc-l`UPTIME=`uptime`check_root(){if["$UID"-ne"$ROOT_ID"];thenecho"Youarenotallowedtoexecutethisprogram!"exit1;fi}print_sys_info(){echo"SystemTime:$DATE"echo"Numberofusers:$NO_USERS"echo"SystemUptime:$UPTIME"}check_rootprint_sys_infoexit0现在再次检查语法。$sudobash-nsys_info.sh上面的命令不会产生任何输出,因为我们的脚本在语法上是正确的。我们还可以再次跟踪脚本执行,它应该工作得很好:$sudobash-xsys_info.sh跟踪shell脚本执行现在运行脚本。$sudo./sys_info.sh用shell脚本显示日期、时间和运行时间shell跟踪执行的重要性Shell脚本跟踪可以帮助我们识别语法错误,更重要的是逻辑错误。比如sys_info.shshell脚本中的check_root函数,这个函数用来判断用户是否是root,因为该脚本只允许超级用户执行。check_root(){if["$UID"-ne"$ROOT_ID"];thenecho"Youarenotallowedtoexecutethisprogram!"exit1;fi}这里的魔法是由if语句表达式["$UID"-ne"$ROOT_ID"]控制的,一旦我们不使用适当的数字运算符(示例中的-ne,表示不相等),我们就会出现逻辑错误。假设我们使用-eq(意思是相等),这将允许任何系统用户以及root运行脚本,因此是一个逻辑错误。check_root(){if["$UID"-eq"$ROOT_ID"];thenecho"Youarenotallowedtoexecutethisprogram!"exit1;fi}注意:正如我们在本系列开头介绍的,可以在特定的环境中激活setshell内置命令部分shell脚本调试。因此,下面一行将帮助我们通过跟踪脚本的执行找到其中的逻辑错误:Scriptwithlogicerror:#!/bin/bash#scripttoprintbriefsysteminfoROOT_ID="0"DATE=`date`NO_USERS=`who|wc-l`UPTIME=`uptime`check_root(){if["$UID"-eq"$ROOT_ID"];thenecho"Youarenotallowedtoexecutethisprogram!"exit1;fi}print_sys_info(){echo"SystemTime:$DATE"echo"用户数:$NO_USERS"echo"SystemUptime:$UPTIME"}#turningonandoffdebuggingofcheck_rootfunctionset-x;check_root;set+x;print_sys_infoexit0保存文件并调用脚本,在输出中我们可以看到普通系统用户无需sudo即可运行脚本。这是因为USER_ID的值为100,不等于root的ROOT_ID为0。欢迎在下面的反馈框中向我们提出有关本文或本系列的问题或反馈。关于作者:AaronKili是Linux和F.O.S.S爱好者、未来的Linux系统管理员、Web开发人员和当前的TecMint内容创建者,他热爱使用计算机工作并且坚信分享知识。
