文章目录
官方手册:https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
一、常用set命令属性
set -o
可以查看所有属性
二、set -e
说明
"Exit immediately if a simple command exits with a non-zero status."
也就是说,在"set -e"之后出现的代码,一旦出现了返回值非零,整个脚本就会立即退出。
示例
set -e
ls a.txt | echo "hi" >/dev/null
echo $?
echo "test"
执行结果:
没有a.txt文件,但是ls a.txt | echo “hi” >/dev/null的返回码是0,因为set -e只捕获最后一个管道命令的返回值,从而导致遇错不退出脚本,依然执行后面的echo “test”
更好的方法是使用set -o pipefail
三、set -o pipefail
说明
"If set, the return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status,or zero if all commands in the pipeline exit successfully. This option is disabled by default."
设置了这个选项以后,包含管道命令的语句的返回值,会变成最后一个返回非零的管道命令的返回值
示例
set -o pipefail
ls a.txt | echo "hi" >/dev/null
[[ $? -ne 0 ]] && exit 1
echo "test"
执行结果:
set -o pipefail是去捕获最后一个返回非零的管道命令的返回值,也就是ls a.txt的返回值;
没有a.txt文件,返回值为非0,因此[[ $? -ne 0 ]]条件成立,脚本退出,不执行echo “test”
四、set +h
hashall
可以让Bash记录执行过的命令路径,并保存到一个内存的Hash表
中,当再次执行相同命令时就不需要再通过PATH变量查找该命令的路径,这样可以提高效率。
但有时,程序的路径发生了变化,因为有Hash记录的存在反而会导致命令执行失败
[root@localhost ~]# hash
命中 命令
7 /usr/bin/openssl
1 /usr/bin/date
1 /usr/bin/tr
1 /usr/bin/uuidgen
1 /usr/bin/strings
4 /usr/bin/md5sum
如果将md5sum命令移动到/usr/local/bin/目录,此时系统依然根据Hash表记录的位置执行命令,就无法找到md5sum命令
[root@localhost ~]# mv /usr/bin/md5sum /usr/local/bin/
[root@localhost ~]# md5sum
-bash: /usr/bin/md5sum: 没有那个文件或目录
可以使用hash -d
删除某个记录信息,或者使用hash -r
清空整个Hash表,再或者使用set +h
禁用hash表来解决这个问题
[root@localhost ~]# set +h #禁用hash表
[root@localhost ~]# hash
-bash: hash: 哈希已禁用
[root@localhost ~]# md5sum /etc/passwd #命令可以正常使用
6322f6fcbc6e157963f5aa74f9e35039 /etc/passwd
五、set -u
开启nounset
属性可以有效防止变量未定义的错误
a.sh脚本:
set -u
useradd $1
执行结果:没有给$1赋值,会报错
[root@localhost shell]# bash a.sh
a.sh:行4: $1: 为绑定变量
六、set -x
打开脚本调试功能,也可以通过bash -x ***.sh打开
如果输出结果以双加号(++)开头则表示命令在子Shell中执行
七、set -n
检查shell语法,但不会执行,等同于bash -n xxx.sh