网管联盟 | 网管论坛 | 网管u家 | 网管博客 | 网管软件 | 网管求职 | 小游戏 | 网管搜索 | 网管原创 | 网管聚合 | 网管读摘 | 网管焦点 | 世界素材 | 会员投稿 | 会员中心 
中国网管联盟
Windows Linux Cisco 网络技术 数据库 黑客攻防 DotNet Java PHP 认证 新闻资讯 服务器 存储资讯 网络设备 网管学堂 技术专题 焦点 网吧频道
 当前位置: > bitsCN.com > linux > Linux编程 > SHELL编程 > Shell脚本调试技术  

Shell脚本调试技术

2007-08-01  作者:bitsCN整理  来源:中国网管联盟  点评 投稿 收藏

    本文全面系统地介绍了shell脚本调试技术,包括使用echo, tee, trap等命令输出关键信息,跟踪变量的值,在脚本中植入调试钩子,使用“-n”选项进行shell脚本的语法检查, 使用“-x”选项实现shell脚本逐条语句的跟踪,巧妙地利用shell的内置变量增强“-x”选项的输出信息等。

网管u家u.bitsCN.com

    一. 前言

中国网管联盟bitsCN.com

    shell编程在unix/linux世界中使用得非常广泛,熟练掌握shell编程也是成为一名优秀的unix/linux开发者和系统管理员的必经之 路。脚本调试的主要工作就是发现引发脚本错误的原因以及在脚本源代码中定位发生错误的行,常用的手段包括分析输出的错误信息,通过在脚本中加入调试语句, 输出调试信息来辅助诊断错误,利用调试工具等。但与其它高级语言相比,shell解释器缺乏相应的调试机制和调试工具的支持,其输出的错误信息又往往很不 明确,初学者在调试脚本时,除了知道用echo语句输出一些信息外,别无它法,而仅仅依赖于大量的加入echo语句来诊断错误,确实令人不胜其繁,故常见 初学者抱怨shell脚本太难调试了。本文将系统地介绍一些重要的shell脚本调试技术,希望能对shell的初学者有所裨益。 网管u家u.bitscn@com

    本文的目标读者是unix/linux环境下的开发人员,测试人员和系统管理员,要求读者具有基本的shell编程知识。本文所使用范例在Bash3.1 +Redhat Enterprise Server 4.0下测试通过,但所述调试技巧应也同样适用于其它shell。 网管下载dl.bitscn.com

    二. 在shell脚本中输出调试信息

网管下载dl.bitscn.com

    通过在程序中加入调试语句把一些关键地方或出错的地方的相关信息显示出来是最常见的调试手段。Shell程序员通常使用echo(ksh程序员常使用 print)语句输出信息,但仅仅依赖echo语句的输出跟踪信息很麻烦,调试阶段在脚本中加入的大量的echo语句在产品交付时还得再费力一一删除。针 对这个问题,本节主要介绍一些如何方便有效的输出调试信息的方法。 网管联盟bitsCN@com

    1. 使用trap命令

网管u家u.bitsCN.com

    trap命令用于捕获指定的信号并执行预定义的命令。
    其基本的语法是:
    trap 'command' signal
    其中signal是要捕获的信号,command是捕获到指定的信号之后,所要执行的命令。可以用kill –l命令看到系统中全部可用的信号名,捕获信号后所执行的命令可以是任何一条或多条合法的shell语句,也可以是一个函数名。
    shell脚本在执行时,会产生三个所谓的“伪信号”,(之所以称之为“伪信号”是因为这三个信号是由shell产生的,而其它的信号是由操作系统产生的),通过使用trap命令捕获这三个“伪信号”并输出相关信息对调试非常有帮助。 网管下载dl.bitscn.com

    表 1. shell伪信号
    信号名 何时产生
    EXIT 从一个函数中退出或整个脚本执行完毕
    ERR 当一条命令返回非零状态时(代表命令执行不成功)
    DEBUG 脚本中每一条命令执行之前 网管网www.bitscn.com

    通过捕获EXIT信号,我们可以在shell脚本中止执行或从函数中退出时,输出某些想要跟踪的变量的值,并由此来判断脚本的执行状态以及出错原因,其使用方法是:
    trap 'command' EXIT 或 trap 'command' 0

网管联盟bitsCN_com

    通过捕获ERR信号,我们可以方便的追踪执行不成功的命令或函数,并输出相关的调试信息,以下是一个捕获ERR信号的示例程序,其中的$LINENO是一个shell的内置变量,代表shell脚本的当前行号。

网管u家u.bitscn@com

    $ cat -n exp1.sh     1  ERRTRAP()     2  {     3    echo "[LINE:$1] Error: Command or function exited with status $?"     4  }     5  foo()     6  {     7    return 1;     8  }     9  trap 'ERRTRAP $LINENO' ERR    10  abc    11  foo

网管联盟bitsCN_com


    其输出结果如下:

网管网www.bitscn.com

    $ sh exp1.shexp1.sh: line 10: abc: command not found[LINE:10] Error: Command or function exited with status 127[LINE:11] Error: Command or function exited with status 1

网管论坛bbs_bitsCN_com


    在调试过程中,为了跟踪某些变量的值,我们常常需要在shell脚本的许多地方插入相同的echo语句来打印相关变量的值,这种做法显得烦琐而笨拙。而通过捕获DEBUG信号,我们只需要一条trap语句就可以完成对相关变量的全程跟踪。

中国网管联盟bitsCN.com

    以下是一个通过捕获DEBUG信号来跟踪变量的示例程序:

网管bitscn_com

    $ cat –n exp2.sh     1  #!/bin/bash     2  trap 'echo “before execute line:$LINENO, a=$a,b=$b,c=$c”' DEBUG     3  a=1     4  if [ "$a" -eq 1 ]     5  then     6     b=2     7  else     8     b=1     9  fi    10  c=3    11  echo "end" 网管联盟bitsCN_com

    其输出结果如下:

网管u家u.bitsCN.com

    $ sh exp2.shbefore execute line:3, a=,b=,c=before execute line:4, a=1,b=,c=before execute line:6, a=1,b=,c=before execute line:10, a=1,b=2,c=before execute line:11, a=1,b=2,c=3end 网管下载dl.bitscn.com

    从运行结果中可以清晰的看到每执行一条命令之后,相关变量的值的变化。同时,从运行结果中打印出来的行号来分析,可以看到整个脚本的执行轨迹,能够判断出哪些条件分支执行了,哪些条件分支没有执行。

中国网管论坛bbs.bitsCN.com

网管u家u.bitsCN.com


TAGs   技术   调试   脚本   执行   shell   命令   输出   使用   选项   可以      
 上一篇:实验:Shell实践与设计   下一篇:UNIX和LINUX系统的SHELL正则表达式语法
Shell脚本调试技术 评论:
loading.. 评论加载中…
评论:请自觉遵守互联网相关政策法规,评论不得超过250字。

验证码: 注册用户
本类热门排行:
最新推荐文章:
网管论坛交流: