看完这篇,写的Shell脚本更加健壮了!

如果秉承着能跑就行的态度写shell脚本,是很自在的,但是如果你想要写出健壮,可靠的shell脚本,可没那么容易。那么有什么可操作的经验或者方法吗? 2020-12-09 08:35:45 Shell脚本语法 巴西航空工业公司被勒索软件“撕票” 近日,由于拒绝支付赎金,巴西航空工业公司(Embraer)被勒索软件团伙RansomExx“撕票”——黑客将上个月在勒索软件攻击中窃取的Embraer公司的敏感数据泄露到了一个新的暗网站点上。 2020-12-09 08:20:43 勒索软件赎金攻击 警方介入成都确诊女子隐私泄露 一夜跑四酒吧被骂翻天 成都确诊女子隐私也已经在网络上大肆泄露。针对成都确诊女子隐私泄露,事件警方回应称已介入。

如果秉承着能跑就行的态度写shell脚本,是很自在的,但是如果你想要写出健壮,可靠的shell脚本,可没那么容易。那么有什么可操作的经验或者方法吗?

[[356512]]

本文转载自微信公众号「编程珠玑」,作者守望先生 。转载本文请联系编程珠玑公众号。

如果秉承着能跑就行的态度写shell脚本,是很自在的,但是如果你想要写出健壮,可靠的shell脚本,可没那么容易。那么有什么可操作的经验或者方法吗?

语法检查

第一个最简单的方法就是利用工具对脚本进行检查,这一部分已经在《有了这个神器,再也不怕shell写不对了》中介绍过了,它能最大程度地发现shell脚本中存在的语法错误,如果你还不知道,建议你绝对不要错过。

而为了保证脚本健壮可靠,那么就需要保证脚本在一些特殊的情况及早出现,避免漏网之鱼。来看看有哪些可行的技巧。

脚本失败时即退出

可以在脚本的开头设置如下:

  1. set-e

举个例子:

  1. #!/bin/bash
  2. set-e
  3. lp#这里运行会出错
  4. date

这种情况下,运行一旦出错就会退出,不放过一个问题:

  1. $./test.sh
  2. lp:Error-nodefaultdestinationavailable.

当然了,这也有不好的地方,有时候命令执行本来就可能是失败的,你还是希望它继续,可以临时加上|| true:

  1. #!/bin/bash
  2. set-e
  3. lp||true
  4. date

不过个人觉得这样的设置用处不是特别大,因为很多时候就是需要处理不同的错误情况,而这样只能要么遇到错误退出,要么认为正确,导致无法走到异常分支。

通过set +e设置回来:

  1. set-e
  2. #command
  3. set+e
  4. #othercommand

打印脚本执行过程

调试阶段,你可能想知道整个过程是执行了哪些命令,每条命令都具体执行了什么,可以利用下面的方式执行:

  1. sh-xtest.sh

或者,和上面类似,在开头加上set -x:

  1. //来源:公众号【编程珠玑】
  2. //作者:守望先生
  3. #!/bin/bash
  4. set-x
  5. if[$#-lt1]
  6. then
  7. echo"nopara"
  8. else
  9. echo"para1$1"
  10. fi

执行时,输出如下:

  1. +[0-le1]
  2. +echonopara
  3. nopara

前面带+的内容就是命令实际执行的,你可以看到比较条件是什么,变量被展开成了具体内容,走到了哪个分支,非常清楚。

显示未定义的变量

shell中变量没有定义,仍然是可以使用的,但是它的结果可能不是你所预期的。举个例子:

  1. //来源:公众号【编程珠玑】
  2. //作者:守望先生
  3. #!/bin/bash
  4. if["$var"="abc"]
  5. then
  6. echo"notabc"
  7. else
  8. echo"abc"
  9. fi

这里本来想判断var的内容是否为abc,实际上var并没有定义,但是在这里使用并没有报错,如果我们想早点发现这类问题,避免在复杂的脚本中问题被掩盖,那么可以在开头加上

  1. set-u

再次运行就会提示:

  1. test.sh:5:test.sh:num:parameternotset

再想象一下,你本来想删除:

  1. rm-rf$dir/*

然后dir是空的时候,变成了什么?

是不是有种后背发凉的感觉?

管道命令一个失败时整个失败

有时候我们可能会执行类似这样的命令:

  1. cattest.sh|grepif|cut-d';'-f2

三条命令一行执行,如果我们希望在其中一条失败,整个命令就失败,而避免执行后面无意义的命令,那么可以在开始设置:

  1. set-opipefail

不设置的情况下,cat test.sh即使执行失败了,后面的grep实际上还会继续执行,可能会导致一些意想不到的情况发生,如果不想这样的情况发生,那么这样设置是有帮助的。

对于静态变量使用readonly

通常我们会在脚本开头定义一些静态变量:

  1. MY_PATH=/usr/bin

而为了避免MY_PATH被意外修改,可以这样:

  1. readonlyMY_PATH=/usr/bin

这样的话,一旦后面有命令尝试修改,就会报错。

  1. #!/bin/bash
  2. readonlyMY_PATH=/usr/bin
  3. MY_PATH=/usr/local/bin

运行一下试试:

  1. $./test.sh
  2. test.sh:3:test.sh:MY_PATH:isreadonly

看,给你提示了!

给变量设置可选的初始值

例如:

  1. name=${1:-shouwang}
  2. echo"${name}"

这里让name为$1,即第一个参数,而当它为空时,令name为shouwang。

多条命令执行使用&&

例如:

  1. cmd0;cmd1;cmd1

这里如果cmd0失败了,后面的命令仍然会执行,而如果不希望后面的命令执行,可以使用:

  1. cmd0&&cmd1&&cmd1

使用函数

脚本本身比较短还好,而脚本一旦变长,不使用函数,将使得脚本很难维护,可读性也很差。

总结

实际上最开始介绍的脚本检查工具就已经非常有效了,基本的错误都能检查出来,而其他的内容,更多的是关注于脚本调试,不放过任何一个可能的错误。

最后,还是优先推荐shellcheck工具。地址:https://www.shellcheck.net

作者:守望,linux应用开发者,目前在公众号【编程珠玑】?分享Linux/C/C++/数据结构与算法/工具等原创技术文章和学习资源。

原文链接:https://mp.weixin.qq.com/s/EpCoiHHpCdPcj8kkeRjHjw

©本文为清一色官方代发,观点仅代表作者本人,与清一色无关。清一色对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文不作为投资理财建议,请读者仅作参考,并请自行承担全部责任。文中部分文字/图片/视频/音频等来源于网络,如侵犯到著作权人的权利,请与我们联系(微信/QQ:1074760229)。转载请注明出处:清一色财经

(0)
打赏 微信扫码打赏 微信扫码打赏 支付宝扫码打赏 支付宝扫码打赏
清一色的头像清一色管理团队
上一篇 2023年5月6日 06:05
下一篇 2023年5月6日 06:05

相关推荐

发表评论

登录后才能评论

联系我们

在线咨询:1643011589-QQbutton

手机:13798586780

QQ/微信:1074760229

QQ群:551893940

工作时间:工作日9:00-18:00,节假日休息

关注微信