相关博客
[Blog-1]: Bash语法-Bash选项设置:Set命令
[Blog-2]: Bash语法-Set与Export区分
1.简介
set
命令用来修改 Shell 环境的运行参数,也就是定制环境。
运行参数会被保存在变量
$-
中,代表当前shell的选项设置。这些选项与set
命令设置的选项相对应,它们定义了Shell 的行为和特性。
例如,普通交互shell执行echo $-
会返回himBHs
,z这意味着shell启用了选项:
h
: hashall 选项,使得 Bash 在可执行命令之前,总是执行路径哈希。这可以提高执行命令的速度(因为 Bash 会缓存命令的路径)。i
: Interactive选项,表示这是一个交互式 shell。m
:monitor 选项,使得 Bash 在执行命令时,允许作业控制信号(如 SIGTTIN、SIGTTOU)被传递给被控制的进程。B
:nobraceexpand 选项,禁止 Bash 对大括号 {} 内的表达式进行扩展,即使它们包含空格或由空格分隔的多个单词。H
:histexpand 选项,允许 Bash 对历史扩展进行扩展,即使 shell 不是交互式的。s
:shell 选项,使得 Bash 在读取命令行时,允许 shell 脚本中的特殊字符和引用被解释。
2.使用
顺便提一下,如果命令行下不带任何参数,直接运行set,会显示所有的环境变量和 Shell 函数
常用的四个命令如下
选项(简写) | 详细格式 | 说明 |
---|---|---|
set -o | 通过选项名称修改Bash选项设置 | |
set -u | set -o nounset | 引用空变量时,立即报错退出。用于避免因使用了未初始化变量而导致的错误 |
set -x | set -o xtrace | 在打印结果前,先打印命令 |
set -e | set -o errexit | 发生错误,立即终止 |
无 | set -o pipefail | 管道子命令发生错误,立即终止 |
2.1 检查变量是否为空
当引用空变量时,立即报错退出。用于避免因使用了未初始化变量而导致的错误。
|
|
2.2 在打印结果之前,先打印命令。
在运行结果之前,先输出执行的命令。
|
|
2.3 错误处理
Bash默认配置时,脚本命令执行失败,仍会继续执行后面的命令。会导致错误累积,不利于脚本维护调试。
而set -e
会使脚本发生错误时,立刻终止退出。
2.3.1 ||
+ exit 1
,默认设置下的异常处理
- 通过逻辑或 +
||
+exit 1
通过下面写法,当command
有非零返回值,脚本就会停止执行。防止错误累积
bash首先执行左侧
command
,如果command
执行成功(返回状态0
),则exit 1
不被执行;如果command
执行失败(返回状态非0
),则执行exit 1
;
|
|
也可在退出时增加日志打印:
|
|
- 通过判断命令退出码,打印日志并退出shell
|
|
等同于
|
|
2.3.2 set -e
,异常处理
脚本只要发生错误,就终止执行。但对
|
管道失效,具体原因看 2.4 小节
|
|
2.3.3 例外:命令执行成功,但返回状态非0
如果脚本中,部分命令的返回非空是正常情况,则需要临时关闭
set -e
,来让脚本正常执行。
- 通过
set +e
关闭选项,之后再通过set -e
打开
|
|
- 通过逻辑或
||
,忽略命令的返回状态
左侧命令执行返回
非零
时,执行右侧命令,右侧是echo
或true
等返回状态为0
的命令,会使整体命令返回状态0
,使脚本正常执行。注意与 2.3.1|| exit 1
区分
|
|
2.4 子命令失败,整个管道命令就失败,脚本就会终止执行。
管道命令
,就是多个子命令通过管道运算符|
()组合成为一个大的命令。Bash
会把最后一个子命令的返回值,作为整个命令的返回值。
也就是说,只要最后一个子命令不失败,管道命令总是会执行成功,因此它后面命令依然会执行,set -e
就失效了。
例如
|
|
改为如下写法,解决管道问题
|
|
还有一种会导致
set -e
失效,mkdir /aa/bb/cc || true
,此处的||
是逻辑或,效果是只要有一个命令不失败,则整体也不会失败(即,echo $?
为0)
3. 推荐设置
推荐设置:
-u
, 校验空变量, 即避免变量未初始化-x
, 输出结果前先打印命令-e
, 发生错误,立即终止-o pipefail
, 管道子命令发生错误,立即终止
3.1 Bash脚本内设置
|
|
等同于
|
|
3.2 命令行执行脚本时,增加选项
|
|
4. 参考链接
[注1]: linux-Set命令说明
[注2]: Bash脚本set命令教程-阮一峰