如何在Linux中启用Shell脚本调试系列
译者:geekpi
在shell脚本调试系列[1]中,本文将解释第三种shell脚本调试模式,即shell跟踪shell中执行linux命令,并查看一些示例来演示它怎么工作以及怎样使用它。
本系列的后面部份清晰地阐述了另外两种shell脚本调试模式:详尽模式和句型检测模式,并用便于理解的事例展示了怎样在这种模式下启用shell脚本调试。
怎样在Linux中启用Shell脚本的调试模式[2]
怎样在Shell脚本中执行句型检测调试模式[3]
shell跟踪简单的来说就是跟踪shell脚本中的命令的执行。要打开shell跟踪,请使用-x调试选项。
这会让shell在终端上显示所有执行的命令及其参数。
我们将使用下边的sys_info.shshell脚本,它会简略地复印出你的系统日期和时间、登录的用户数和系统的运行时间。不过,脚本中包含我们须要查找和更正的句型错误。
#!/bin/bash
# script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
}
print_sys_info(){
echo "System Time : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime : $UPTIME
}
check_root
print_sys_info
exit 0
保存文件并执行脚本。脚本只能用root用户运行,因而如下使用sudo命令[4]运行:
$ chmod +x sys_info.sh
$ sudo bash -x sys_info.sh
shell跟踪-显示脚本中的错误
从前面的输出我们可以观察到,首先执行命令,之后其输出做为一个变量的值。
比如,先执行date,其输出做为变量DATE的值。
我们可以执行句型检测来只显示其中的句型错误,如下所示:
$ sudo bash -n sys_info.sh
脚本中句型检测
假如我们考量这个shell脚本,我们都会发觉if句子缺乏了封闭条件的fi关键字。为此,让我们加上它,新的脚本应当看上去像这样:
#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
print_sys_info(){
echo "System Time : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime : $UPTIME
}
check_root
print_sys_info
exit 0
再度保存文件并以root执行,同时做句型检测:
$ sudo bash -n sys_info.sh
在shell脚本中执行句型检测
里面的句型检测操作的结果依然显示在脚本的第21行还有一个错误。所以,我们依然要纠正一些句型。
再一次剖析脚本,会发觉第21行的错误是因为在print_sys_info函数内最后一个echo命令[5]中没有闭合双冒号”。
我们将在echo命令中添加闭合双冒号并保存文件。更改过的脚本如下:
#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
print_sys_info(){
echo "System Time : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime : $UPTIME"
}
check_root
print_sys_info
exit 0
如今再一次复查句型。
$ sudo bash -n sys_info.sh
里面的命令不会形成任何输出,由于我们的脚本句型上正确。我们也可以再度跟踪脚本执行,它应当工作得挺好:
$ sudo bash -x sys_info.sh
跟踪shell脚本执行
如今运行脚本。
$ sudo ./sys_info.sh
用shell脚本显示日期、时间和运行时间
shell跟踪执行的重要性
shell脚本跟踪可以帮助我们辨识句型错误,更重要的是辨识逻辑错误。比如,在sys_info.shshell脚本中的check_root函数,它用于确定用户是否为root,由于脚本只容许由超级用户执行。
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
这儿的魔法是由if句子表达式[“$UID”-ne”$ROOT_ID”]控制的,一旦我们不使用合适的数字运算符(示例中为-ne红旗linux操作系统,这意味着不相等),我们最终可能会出一个逻辑错误。
假定我们使用-eq(意思是等于),这将容许任何系统用户以及root用户运行脚本,因而是一个逻辑错误。
check_root(){
if [ "$UID" -eq "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
注意:我们在本系列开头介绍过,set这个shell外置命令可以在shell脚本的特定部份激活调试。
为此,下边的行将帮助我们通过跟踪脚本的执行在其中找到这个逻辑错误:
具有逻辑错误的脚本:
#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -eq "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
print_sys_info(){
echo "System Time : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime : $UPTIME"
}
#turning on and off debugging of check_root function
set -x ; check_root; set +x ;
print_sys_info
exit 0
保存文件并调用脚本,在输出中,我们可以见到一个普通系统用户可以在未sudo的情况下运行脚本。这是由于USER_ID的值为100,不等于为0的root的ROOT_ID。
$ ./sys_info.sh
RunShellScriptWithoutSudo
未sudo的情况下运行shell脚本
这么,如今我们早已完成了shell脚本调试系列[6],可以在下边的反馈栏里给我们关于本篇或则本系列提出问题或反馈。
作者简介:
AaronKili是Linux和F.O.S.S爱好者,将来的LinuxSysAdmin、web开发人员shell中执行linux命令linux学习论坛,目前是TecMint的内容创作者,他喜欢用笔记本工作,并深信分享知识。
via:
作者:AaronKili[7]译者:geekpi校对:jasminepeng
本文由LCTT[8]原创编译,Linux中国荣誉推出