如何使用Shell跟踪跟踪Shell脚本中的命令执行

在本文的 shell脚本调试系列中 ,我们将解释第三种shell脚本调试模式,即shell跟踪,并查看一些示例来演示它如何工作,以及如何使用它。 本系列的前面部分清楚地阐明了另外两种shell脚本调试模式: 详细模式语法检查模式,以及如何在这些模式下启用shell脚本调试的易于理解的示例。
  1. 如何在Linux中启用Shell脚本调试模式 - 第1部分
  2. 如何在Shell脚本中执行语法检查调试模式 - 第2部分
Shell跟踪只是跟踪shell脚本中的命令的执行。 要打开shell跟踪,请使用 -x调试选项。 这指示shell在终端上执行时显示所有命令及其参数。 我们将使用下面的 sys_info.sh 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" -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命令运行它如下所示:
$ chmod +x sys_info.sh
$ sudo bash -x sys_info.sh

Shell跟踪 - 在脚本中显示错误

从上面的输出,我们可以观察到,命令首先在其输出被替换为变量的值之前执行。 例如,首次执行 日期 ,并且其输出被替换为变量 DATE的值。 我们可以执行语法检查,以仅显示语法错误,如下所示:
$ sudo bash -n sys_info.sh 

语法检查脚本

如果我们仔细观察shell脚本,我们将意识到 if statement缺少一个闭合的 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命令中缺少闭合双引号 (”) 。 我们将在 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.sh shell脚本中的 check_root函数,它用于确定用户是否为root,因为脚本只允许由超级用户执行。
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
魔术在这里被控制的 if statement表达 [ "$UID" -ne "$ROOT_ID" ] ,一旦我们不使用合适的数字运算符( -ne在这种情况下,这意味着不相等),我们结束了一个可能的逻辑错误。 假设我们使用 -eq (意思等于),这将允许任何系统用户以及root用户运行脚本,因此是一个逻辑错误。
check_root(){
if [ "$UID" -eq "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
注意 :我们在本系列开头介绍的是,shell 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 ,不等于根 ROOT_ID0
$ ./sys_info.sh

运行Shell脚本而不使用Sudo

那么,这是现在,我们已经到了 shell脚本调试系列的末尾,下面的响应形式可以用于解决任何问题或反馈给我们,关于本指南或整个3部分系列。
赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏