如何写出健壮可靠的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

 

posted @   春困秋乏夏打盹  阅读(210)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
历史上的今天:
2019-08-27 H3C 模拟器 pc与防火墙,交换机相连,在pc cmd下用telnet访问交换机和防火墙
2019-08-27 H3C 模拟器 pc与sw直连 登录web
2019-08-27 H3C 模拟器 pc与sw直连 开启telnet
点击右上角即可分享
微信分享提示