译者:geekpi
在shell脚本调试系列[1]中,本文将解释第三种shell脚本调试模式,即shell跟踪shell中执行linux命令,并查看一些示例来演示它怎么工作以及怎样使用它。
本系列的后面部份清晰地阐述了另外两种shell脚本调试模式:详尽模式和句型检测模式,并用便于理解的事例展示了怎样在这种模式下启用shell脚本调试。
怎样在Linux中启用Shell脚本的调试模式[2]
怎样在Shell脚本中执行句型检测调试模式[3]
shell跟踪简单的来说就是跟踪shell脚本中的命令的执行。要打开shell跟踪,请使用-x调试选项。
这会让shell在终端上显示所有执行的命令及其参数。
我们将使用下边的sys_info.shshell脚本,它会简略地复印出你的系统日期和时间、登录的用户数和系统的运行时间。不过,脚本中包含我们须要查找和更正的句型错误。

  1. #!/bin/bash
  2. # script to print brief system info
  3. ROOT_ID="0"
  4. DATE=`date`
  5. NO_USERS=`who | wc -l`
  6. UPTIME=`uptime`
  7. check_root(){
  8.  if [ "$UID" -ne "$ROOT_ID" ]; then
  9.    echo "You are not allowed to execute this program!"
  10.    exit 1;    
  11. }
  12. print_sys_info(){
  13.  echo "System Time    : $DATE"
  14.  echo "Number of users: $NO_USERS"
  15.  echo "System Uptime  : $UPTIME
  16. }
  17. check_root
  18. print_sys_info
  19. exit 0

保存文件并执行脚本。脚本只能用root用户运行,因而如下使用sudo命令[4]运行:

  1. $ chmod +x sys_info.sh
  2. $ sudo bash -x sys_info.sh

shell跟踪-显示脚本中的错误
从前面的输出我们可以观察到,首先执行命令,之后其输出做为一个变量的值。
比如,先执行date,其输出做为变量DATE的值。
我们可以执行句型检测来只显示其中的句型错误,如下所示:

  1. $ sudo bash -n sys_info.sh

脚本中句型检测
假如我们考量这个shell脚本,我们都会发觉if句子缺乏了封闭条件的fi关键字。为此,让我们加上它,新的脚本应当看上去像这样:
awk 执行shell命令_shell中执行linux命令_执行shell脚本命令

  1. #!/bin/bash
  2. #script to print brief system info
  3. ROOT_ID="0"
  4. DATE=`date`
  5. NO_USERS=`who | wc -l`
  6. UPTIME=`uptime`
  7. check_root(){
  8.  if [ "$UID" -ne "$ROOT_ID" ]; then
  9.    echo "You are not allowed to execute this program!"
  10.    exit 1;
  11.  fi    
  12. }
  13. print_sys_info(){
  14.  echo "System Time    : $DATE"
  15.  echo "Number of users: $NO_USERS"
  16.  echo "System Uptime  : $UPTIME
  17. }
  18. check_root
  19. print_sys_info
  20. exit 0

再度保存文件并以root执行,同时做句型检测:

  1. $ sudo bash -n sys_info.sh

在shell脚本中执行句型检测
里面的句型检测操作的结果依然显示在脚本的第21行还有一个错误。所以,我们依然要纠正一些句型。
再一次剖析脚本,会发觉第21行的错误是因为在print_sys_info函数内最后一个echo命令[5]中没有闭合双冒号”。
我们将在echo命令中添加闭合双冒号并保存文件。更改过的脚本如下:

  1. #!/bin/bash
  2. #script to print brief system info
  3. ROOT_ID="0"
  4. DATE=`date`
  5. NO_USERS=`who | wc -l`
  6. UPTIME=`uptime`
  7. check_root(){
  8.  if [ "$UID" -ne "$ROOT_ID" ]; then
  9.    echo "You are not allowed to execute this program!"
  10.    exit 1;
  11.  fi
  12. }
  13. print_sys_info(){
  14.  echo "System Time    : $DATE"
  15.  echo "Number of users: $NO_USERS"
  16.  echo "System Uptime  : $UPTIME"
  17. }
  18. check_root
  19. print_sys_info
  20. exit 0

如今再一次复查句型。
执行shell脚本命令_shell中执行linux命令_awk 执行shell命令

  1. $ sudo bash -n sys_info.sh

里面的命令不会形成任何输出,由于我们的脚本句型上正确。我们也可以再度跟踪脚本执行,它应当工作得挺好:

  1. $ sudo bash -x sys_info.sh

跟踪shell脚本执行
如今运行脚本。

  1. $ sudo ./sys_info.sh

用shell脚本显示日期、时间和运行时间
shell跟踪执行的重要性
shell脚本跟踪可以帮助我们辨识句型错误,更重要的是辨识逻辑错误。比如,在sys_info.shshell脚本中的check_root函数,它用于确定用户是否为root,由于脚本只容许由超级用户执行。

  1. check_root(){
  2.  if [ "$UID" -ne "$ROOT_ID" ]; then
  3.    echo "You are not allowed to execute this program!"
  4.    exit 1;
  5.  fi
  6. }

这儿的魔法是由if句子表达式[“$UID”-ne”$ROOT_ID”]控制的,一旦我们不使用合适的数字运算符(示例中为-ne红旗linux操作系统,这意味着不相等),我们最终可能会出一个逻辑错误。
假定我们使用-eq(意思是等于),这将容许任何系统用户以及root用户运行脚本,因而是一个逻辑错误。

  1. check_root(){
  2.  if [ "$UID" -eq "$ROOT_ID" ]; then
  3.    echo "You are not allowed to execute this program!"
  4.    exit 1;
  5.  fi
  6. }

注意:我们在本系列开头介绍过,set这个shell外置命令可以在shell脚本的特定部份激活调试。
为此,下边的行将帮助我们通过跟踪脚本的执行在其中找到这个逻辑错误:
具有逻辑错误的脚本:

  1. #!/bin/bash
  2. #script to print brief system info
  3. ROOT_ID="0"
  4. DATE=`date`
  5. NO_USERS=`who | wc -l`
  6. UPTIME=`uptime`
  7. check_root(){
  8.  if [ "$UID" -eq "$ROOT_ID" ]; then
  9.    echo "You are not allowed to execute this program!"
  10.    exit 1;
  11.  fi
  12. }
  13. print_sys_info(){
  14.  echo "System Time    : $DATE"
  15.  echo "Number of users: $NO_USERS"
  16.  echo "System Uptime  : $UPTIME"
  17. }
  18. #turning on and off debugging of check_root function
  19. set -x ; check_root;  set +x ;
  20. print_sys_info
  21. exit 0

保存文件并调用脚本,在输出中,我们可以见到一个普通系统用户可以在未sudo的情况下运行脚本。这是由于USER_ID的值为100,不等于为0的root的ROOT_ID。

  1. $ ./sys_info.sh

awk 执行shell命令_执行shell脚本命令_shell中执行linux命令
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中国荣誉推出