查看原文
其他

Shell基础(6)-set命令实现脚本安全

Cloud研习社 Cloud研习社 2023-06-06



每周二、四、六定期更新!


set命令用来修改shell环境的运行参数,也就是可以定制环境。本文介绍四个比较重要的参数。set命令不加任何参数,将会显示所有的环境变量和shell函数
[root@studyclub jason]# type set
set is a shell builtin # set是一个内部命令

[root@studyclub ~]# set [-uex]
选项与参数:
-u  :当变量没有定义时,会显示错误信息;
-e  :如果一个命令返回一个非0退出状态值(失败)就退出
-x  :当命令执行时,打印命令及其参数


我们通过实例来看看:实例1:使用了没有定义的变量(验证set -u)
第一步:我们不用set -u
[root@studyclub jason]# cat test_set.sh
#!/bin/bash
#
# **************************************************************
# Author: Jason Zhuo
# Create time: 2021年7月1日17:26:59
# Description: this is a test file for set
# File name: test_set.sh
# Copyright (C): 2021 All rights reserved
# **************************************************************
Dir=/data
touch $Dirr/a.txt # 我们希望在/data目录下创建一个a.txt文件,但是这个地方我们在使用变量的时候把Dir写成了Dirr。


执行一下看看效果:
[root@studyclub jason]# sh test_set.sh
before
after
找一下文件:
[root@studyclub jason]# ls         # 结果没有我们想要的a.txt文件,为什么呢?


上面的练习,我们没有在/data目录下找到我们想要的a.txt文件,这是因为我们在使用变量的时候把Dir写成了Dirr,Dirr变量不存在,所以系统就会认为这是个空的变量,所以执行“touch $Dirr/a.txt”就相当于执行“touch /a.txt”,好了,我们去根目录"/"下看看是不是找到了那个a.txt文件呢?我们这里是一个touch命令,如果是rm命令呢,是不是很危险。所以为了保证脚本执行的安全性,我们需要在遇到这种情况时提示错误信息,而不是继续错误的执行脚本:
# 好了,我们把脚本改成下面的样子:即加上set -u
[root@studyclub jason]# cat test_set.sh
#!/bin/bash
#
# **************************************************************
# Author: Jason Zhuo
# Create time: 2021年7月1日17:26:59
# Description: this is a test file for set
# File name: test_set.sh
# Copyright (C): 2021 All rights reserved
# **************************************************************
set -u
Dir=/data
echo "before"
touch $Dirr/a.txt
echo "after"

# 执行一下看看效果:
[root@studyclub jason]# sh test_set.sh
before
test_set.sh: line 13: Dirr: unbound variable     # 看到了吗,遇到了没有定义的变量,自动报错了


加上set -u选项以后,脚本执行过程中遇到没有定义的变量的时候会自动报错而不是把它作为空字符去处理。这次我们的练习在touch命令的前后都加了显示信息,目的是为了看看遇到错误的时候,shell脚本会怎么处理,通过上面的实验我们可以发现,有错误的脚本,不是全都执行,也不是都不执行,而是在出错之前的位置的命令会全部执行,出错之后的命令都不执行,出错的地方阻止了脚本的执行。实例2:命令执行错误后退出(验证set -e)


[root@studyclub jason]# vim test_set.sh

#!/bin/bash
#
# **************************************************************
# Author: Jason Zhuo
# Create time: 2021年7月1日17:26:59
# Description: this is a test file for set
# File name: test_set.sh
# Copyright (C): 2021 All rights reserved
# **************************************************************
set -e # 加上这个set -e,设置shell为命令执行出错后退出,后面的命令也不执行了
Dir=/data
echo "before"
touc $Dir/a.txt         # 故意写错一个命令
echo "after"

[root@studyclub jason]# sh test_set.sh
before
test_set.sh: line 13: touc: command not found # 看到了吗,echo "after"那个命令没有执行。

# 如果我们把脚本里的set -e去掉,再来验证一下
[root@studyclub jason]# sh test_set.sh
before
test_set.sh: line 12: touc: command not found
after         # 最后的echo "after"那个命令被执行了。


小结:
  • set -e判断的是命令执行的返回值(我们前面提到获取命令执行结果返回值的方法:echo $?),如果不为0,则认为出错,终止当前脚本的执行。

  • 当然为了让-u 和-e两个同时生效,我们可以写成set -ue

实例3:显示当前执行的命令(set -x)
[root@studyclub jason]# cat test_set.sh
#!/bin/bash
#
# **************************************************************
# Author: Jason Zhuo
# Create time: 2021年7月1日17:26:59
# Description: this is a test file for set
# File name: test_set.sh
# Copyright (C): 2021 All rights reserved
# **************************************************************
set -x # 加上-x选项,显示当前的执行命令,在需要跟踪执行过程的时候非常有用
Dir=/data
echo "before"
touch $Dir/a.txt
echo "after"

[root@studyclub jason]# bash test_set.sh # 我们执行一下,看看效果
+ Dir=/data
+ echo before
before
+ touch /data/a.txt
+ echo after
after


set -x以后,脚本执行过程中行首带有加号“+”的行就是执行的命令。通过这种方式我们可以跟踪执行了哪些命令。好了,三个选项我们已经通过实例讲解完了,接下来我们看看当前环境,set已经设置了哪些参数:[root@studyclub jason]# echo $-
himBH                 # 这些选项是默认就有的


# 我们添加一个选项,实现“使用未定义的变量时报错”
[root@studyclub jason]# set -u
[root@studyclub jason]# echo $-
himuBH                 # 设置完成后,set的所有设置里多了一个u选项

#
 如果想取消这个“使用未定义的变量时报错”这个功能,我们应该:
[root@studyclub jason]# set +u
[root@studyclub jason]# echo $-
himBH                 # 怎么样,现在u选项已经没有了吧!


小结:


- 通过echo $-命令查看set当前有哪些配置项。

- 在set里减号“-”的意义是添加配置型,加号“+”的意义才是删除某个配置项。

- 实际生产应用中,建议在脚本里加上set -ue,这样可以防止脚本误操作。



手应知:

    尝鲜Rocky Linux

《Linux基础及进阶》:

    049 - Shell基础(1)-bash简介、type
    050 - Shell基础(2)-shell变量及设置规则    051 - Shell基础(3)-环境变量    052 - Shell基础(4)-变量的有效范围、位置变量    053 - Shell基础(5)-退出状态码


看完本文有收获?请分享给更多人


推荐关注「Cloud研习社」,带你从零开始掌握云计算技术!

微信号|bjdream-1


Cloud研习社 · 

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存