测试shell脚本有没有问题 shell脚本测试 shell脚本的调试方法 shell脚本应知应会必知必会

shell 调试方法

shell 在 linux 系统中比较常见,简单的脚本可以看着确实没难度,但是当脚本功能复杂后,看起来就不那么流畅了,所以掌握一些调试方式还是很有必要的,这里我收集了一次常用的调试方式。

shell调试的方法

  1. echo 语句
    通过在脚本代码中插入 echo 语句输出变量值、执行状态等信息,在脚本中直接打印还是比较方便的
  2. shell 脚本本身提供的一些方法
    • -n 读一遍脚本中的命令但不执行,主要用于检查脚本中的语法错误。
    • -v 一边执行脚本,一边将执行过程中的脚本命令打印到标准输出。
    • -x 提供跟踪执行信息,将执行的每一条命令和结果依次打印出来。
    • +x 关闭跟踪执行信息。                                                                                                   echo $?   返回值 0 : 命令成功执行                                                                                   #检测语法,但不实际执行 sh -nv 脚本文件                                                                   #边执行,边显示结果,遇到错误就停止脚本 sh -xv 脚本文件 
  3. trap 命令
    使用 trap 命令可以捕获并处理脚本中的信号或错误。通过在脚本中设置 trap 命令,可以在发生特定事件时执行自定义操作,如输出日志、打印变量值等。
  4. 调试工具
    使用 trap 命令可以捕获并处理脚本中的信号或错误。通过在脚本中设置 trap 命令,可以在发生特定事件时执行自定义操作,如输出日志、打印变量值等。

在脚本中用set命令。

set -xv表示启用;

set +xv表示禁用。

当Shell脚本没有执行出想要的结果或者打印出了一个错误的时候,可以调试一下,看看执行的详细过程,shell脚本不会像python那样可以单步跟踪,而是使用bash -x [需要执行的脚本],一次性把脚本的执行信息全部打出来,如下图:

linux-86:/opt/zsmTest # bash -x ./test.sh

++ ps -ef

++ grep mesos-master

++ grep -v grep

++ awk '{print $2}'

+ mesos_master_pid=16036

+ echo 16036

16036

linux-86:/opt/zsmTest #

每一行前面都会有“+”,“+”越多表示该句代码的嵌套层次越深。在脚本执行中,如果有语法错误或者脚本中写的路径找不到等问题,会直接有错误信息打屏的。

shell脚本必知必会

 这篇文章包含开发shell脚本之前首先要了解的东西、刚接触shell开发容易遇到的常见错误等。其中有些总结是我师傅总结的,我在上增加了些自己的经验和教训,然后再把这些东西发出来给大家共享一下

1.      什么是环境变量

环境变量可以理解为进程内一种特殊的全局变量。在进程的内存中有一个全局变量,这是一个字符串数组,每个字符串里面的内容就是"key=value"形式的环境变量。当使用export增加或者修改一个环境变量时,实际就是修改的__environ数组。当我们输入一个命令时,比如ls,bash解释器就从这个数组中查找PATH环境变量的值,这个值是冒号分隔的目录列表,再按这个目录列表从前往后依次查找ls可执行程序。可以使用gdb调试进程,看到具体的__environ数组的值(详见附件)

2.      由iMAP执行 .  svc_profile.sh看脚本执行方式

在进入iMAP的主目录后首先要执行.  svc_profile.sh,而我们平时执行脚本的时候都是通过“./test.sh”或者“bash test.sh”执行脚本这种方式,那么,这两种方式有何不同呢:

1)       通过“点+空格+脚本”的执行脚本,是当前bash解释器进程读取并执行该脚本,所以svc_profile.sh里面设置的环境变量就会在当前bash进程中生效。在后台登陆sybase数据库时,就需要使用这种方式执行sybase的环境变量,否则会报一个类似于这样的错误:

dbuser@linux:/opt/sybase/ASE-15_0/install> /opt/sybase/ASE-15_0/bin/dataserver: error while loading shared libraries: libsbgse2.so: cannot open shared object file: No such file or directory

原因就是库的路径没有再环境变量里生效就没有找到这个库。

2)       通过“./test.sh”执行脚本过程中,当前bash进程会派生一个子bash进程去读取和执行脚本,脚本中设置的环境变量也就在该子进程中生效了,你的当前bash进程是没有办法办法使用这些环境变量的。

3)       通过“test.sh”执行脚本。由于“./”表示当前目录,所以加上“./”执行脚本表示在当前目录下找这个脚本执行;如果不加,shell解释器会从$PATH环境变量指定的路径里面查找,而通常$PATH里面是没有"."(表示当前路径)的,所以会报找不到shellscript.sh

4)       由于环境变量不是操作系统内核的东西,所以子进程使用的环境变量都是从父进程继承来的。当我们调用execve派生子进程时,第三个参数就是环境变量,操作系统内核会把这个数据传给新进程,最终execve执行完时,__environ数组的内容跟传入的内容是一致的。

int execve(const char *path, char *const argv[],char *const envp[]);

这样子进程就拥有了和父进程相同的环境变量了。另外main函数有一个隐含的参数就是这个环境变量数组的。

5)       经常被继承的环境变量有这些:

语言环境变量:LANG、LC_*、LC_ALL;

语言环境变量决定字符集的处理方式,设置不正确会导致:字符串转码失败、数据库操作失败、界面显示乱码、……等问题。

时区环境变量:TZ;

TZ环境变量决定着进程所用的时区规则,设置不正确会导致:获取本地时间错误、夏令时跳变错误、UTC/本地时间转换错误、……等问题。

可执行文件查找路径:PATH;

PATH环境变量决定了可执行文件的查找路径,设置不正确会导致进程调用外部可执行程序时,如果没有指定路径信息,可能会执行失败。

动态库查找路径:LD_LIBRARY_PATH;

Windows环境中,PATH环境变量即决定可执行文件的查找路径,也决定动态库的查找路径。但在Solaris/Linux环境中,动态库的查找路径由$LD_LIBRARY_PATH决定。如果设置错误,程序在加载或执行过程中会因为动态库找不到而异常退出(这种退出不会产生core文件)。

    根据以上的解释,在执行脚本时就可以清楚地知道要采用哪种方式了。

3.      为什么shell脚本的开头会有#!/bin/bash这一行呢

1)       "#!"就是指定了解释器执行,使用./test.sh的方式来执行脚本的时候就需要加上可执行权限,因为此时./test.sh相当于一个可执行程序。

2)       "#!/bin/bash"是告诉shell解释器,用什么程序来执行这个文件。现在我们把./test.sh的脚本头改成"#!/bin/abc"再执行,我们可以看到报错如下:

linux-86:/opt/zsmTest # ./test.sh

bash: ./test.sh: /bin/ad: bad interpreter: No such file or directory

然后,再改成#!/bin/cat,执行这个脚本时,就会用cat这个命令执行这个脚本,即打印出脚本的内容,相当于执行cat  ./test.sh:

linux-86:/opt/zsmTest # ./test.sh

#!/bin/cat

hadoop_pid=`ps -ef|grep hadoop|grep -v grep|awk '{print $2}'`

echo $ hadoop_pid

4.      Shell脚本的调试

当Shell脚本没有执行出想要的结果或者打印出了一个错误的时候,可以调试一下,看看执行的详细过程,shell脚本不会像python那样可以单步跟踪,而是使用bash -x [需要执行的脚本],一次性把脚本的执行信息全部打出来,如下图:

linux-86:/opt/zsmTest # bash -x ./test.sh

++ ps -ef

++ grep mesos-master

++ grep -v grep

++ awk '{print $2}'

+ mesos_master_pid=16036

+ echo 16036

16036

linux-86:/opt/zsmTest #

每一行前面都会有“+”,“+”越多表示该句代码的嵌套层次越深。在脚本执行中,如果有语法错误或者脚本中写的路径找不到等问题,会直接有错误信息打屏的。

5.      为什么shell脚本在执行的时候必须是unix格式的

因为dos格式是以0x0D 0x0A两个字节做行分隔符的,而unix格式则只以0x0A做行分隔符,也就是0x0D会被解释器当成是这一行的内容,所以就会出现命令找不到等各种比较诡异的异常。当脚本已经是DOS格式时,可以先执行dos2unix [需要执行的脚本],然后再执行脚本即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值