如何写出健壮可靠的shell脚本

1 脚本失败时即退出 ; set -e

例子:

#!/bin/bash
set -e
lp    #这里运行会出错
date
[root@dg1 opt]# sh t1.sh
t1.sh: line 3: lp: command not found

可以在脚本的开头设置如下
set -e

[root@dg1 opt]# vim t1.sh
#!/bin/bash
set -e
lp  || true   #命令执行失败,继续执行
date
[root@dg1 opt]# sh t1.sh 
t1.sh: line 3: lp: command not found
Mon Aug 24 10:14:18 CST 2020

2 打印脚本执行过程

sh -x test.sh #整个过程执行了哪些命令
或者在开头加上set -x

[root@dg1 opt]# cat t2.sh 
#!/bin/bash
set -x
if [ $# -lt 1 ]
then
   echo  "no para"
else
   echo "para 1 $1"
fi
[root@dg1 opt]# ./t2.sh 2
++ '[' 1 -lt 1 ']'
++ echo 'para 1 2'
para 1 2
[root@dg1 opt]# ./t2.sh 
++ '[' 0 -lt 1 ']'
++ echo 'no para'
no para

3 显示未定义的变量:

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

#!/bin/bash
if [ "$var" = "abc" ]
then
   echo  " not abc"
else
   echo " abc "
fi
这里本来想判断var的内容是否为abc,实际上var并没有定义,但是在这里使用并没有报错,在开头加上set -u
[root@dg1 opt]# cat t3.sh 
#!/bin/bash
set -u
if [ "$var" = "abc" ]
then
   echo  " not abc"
else
   echo " abc "
f
[root@dg1 opt]# ./t3.sh 
./t3.sh: line 3: var: unbound variable

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

例如一条命令:cat test.sh |grep if | cut -d ';' -f 2
三条命令一行执行,如果我们希望在其中一条失败,整个命令就失败,而避免执行后面无意义的命令,可以在开头加上set -o pipefail
[root@dg1 opt]# cat t3.sh |grep if |cut -d '=' -f 1
if [ "$var" 
[root@dg1 opt]# cat t3.sh |grep if |cut -d '=' -f 2
 "abc" ]
[root@dg1 opt]# cat t3.sh |grep if |cut -d '=' -f 3

[root@dg1 opt]# cat t3.sh |grep if
if [ "$var" = "abc" ]

5 对于静态变量使用 readonly

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

MY_PATH=/usr/bin

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

readonly MY_PATH=/usr/bin

6 给变量设置可选的初始值

name=${1:-yang}
echo "${name}"
这里让name为$1,即第一个参数,而当它为空时,令name为 yang 

7 多条命令执行使用&&

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

8 使用函数

如果脚本比较长,建议使用函数,便于维护,可读性也比较高

9 可以使用 shellcheck 脚本检查工具

https://www.shellcheck.net/

参考:https://mp.weixin.qq.com/s/uhMxmP_k6uUheOVd3A0GKw

原文地址:https://www.cnblogs.com/yhq1314/p/13572798.html