翼度科技»论坛 云主机 LINUX 查看内容

Linux grep命令与$?命令结合使用技巧

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
今天检查前同事留下的一个shell脚本时,其中一个脚本中有一个业务逻辑处理:要判断Oracle数据库实例是否启动,如果数据库实例处于OPEN状态的话,则执行/运行一些业务逻辑操作。脚本大体如下(脚本做了一下混淆和精简收缩)
  1. up_flag=`${SCRIPT_DIR}/chkdbup.sh ${ORACLE_SID}`

  2. if [ ${up_flag} -eq 0 ]; then 
  3.   .......
  4.   exit
  5. else
  6.   .......
  7. fi
复制代码
其中chkdbup.sh脚本的内容如下:
  1. ps -ef | grep -i smon_${1} | grep -v "grep" >/dev/null 
  2. echo $?
复制代码
Review这个脚本时,我感觉这个脚本的逻辑有问题(我认为这个脚本存在一个逻辑"bug"),主要是等于时表示数据库实例处于启动状态,而{up_flag}不为0时则表示数据库实例异常了
  1. if [ ${up_flag} -eq 0 ]; then 
  2.   .......
  3.   exit
  4. else
  5.   .......
  6. fi
复制代码
在Linux shell脚本中,$?一般表示上一个命令的返回值(执行情况),执行成功,返回0,其他任何数值表示上条命令执行有错误。我认为数据库实例OPEN或关闭或crash的时候,chkdbup.sh这个脚本都会返回0,而不会返回值1,为了验证我的想法,于是我找了台测试环境验证测试一下。当前测试环境下ORACLE_SID为kerry
  1. [oracle@mytestdb ~]$ ps -ef | grep -i smon_kerry | grep -v "grep"
  2. oracle   1338965       1  0 Jul05 ?        00:00:14 ora_smon_kerry
  3. [oracle@mytestdb ~]$ echo $?
  4. 0
复制代码
换一个ORACLE_SID,此时因为Oracle实例不存在,就可以模拟实例Crash的情况(懒得关闭Oracle实例了,这个跟关闭Oracle实例测试效果一致)
  1. [oracle@mytestdb ~]$ ps -ef | grep -i smon_gsp | grep -v "grep"
  2. [oracle@mytestdb ~]$ echo $?
  3. 1
复制代码
按照我的想法/认知,不管这个数据库实例存在或不存在,ps命令总是会执行成功,它就会返回0,而且是永远返回0,但是测试验证结果跟我的想法/认知不符合,Why?查了一些资料,然后和同事讨论后,终于搞清楚了其中的原因,主要是因为$?命令获取的上一条命令的返回结果,而上一条命令中使用了grep命令,而grep命令的返回结果是这样的:如果找到了匹配的相关记录则返回0,如果没有找到匹配的相关记录则返回1,如果执行过程中出错,就返回2,你可以使用man grep查看相关说明,具体如下所示:
  1. EXIT STATUS
  2.        Normally  the  exit status is 0 if a line is selected, 1 if no lines were selected, and 2 if an error occurred.  However,
  3.        if the -q or --quiet or --silent is used and a line is selected, the exit status is 0 even if an error occurred.
复制代码
其实,grep命令在HP-UX下也是同样的返回值,如下所示:
  1.  RETURN VALUE
  2.       Upon completion, grep returns one of the following values:

  3.  Hewlett-Packard Company            - 3 -       HP-UX 11i Version 3 Feb 2007

  4.  grep(1)                                                             grep(1)

  5.            0    One or more matches found.
  6.            1    No match found.
  7.            2    Syntax error or inaccessible file (even if matches were
  8.                 found).
复制代码
所以,我的想法/认知是错误的,而前同事也是在shell脚本中借助grep这个特性和$?来判断Oracle实例是否处于OPEN状态。这个也是一个shell脚本中的一个技巧,只是我很少用这种技巧,另外,由于对grep命令返回的值不清楚(具体来说,不清楚grep没有匹配到相关记录时返回1)。因此闹了一个乌龙事件。
扫描上面二维码关注我如果你真心觉得文章写得不错,而且对你有所帮助,那就不妨帮忙“推荐"一下,您的“推荐”和”打赏“将是我最大的写作动力!本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.
来源:https://www.cnblogs.com/kerrycode/p/17552416.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具