我正在学习如何set
在脚本中有效地使用不同的选项,并且发现set -u
如果变量设置不正确(例如删除用户),这似乎是退出脚本的完美选择。根据男人页面,set -u
并set -e
执行以下操作...
-e Exit immediately if a command exits with a non-zero status.
-u Treat unset variables as an error when substituting.
我创建了一个测试脚本来测试此功能,但它似乎没有按预期工作。也许有人可以更好地向我解释我的问题以及我在哪里误解?测试脚本如下。谢谢。
set -e
set -u
testing="This works"
echo $?
echo ${testing}
testing2=
echo $?
echo ${testing2}
testing3="This should not appear"
echo $?
echo ${testing3}
我希望脚本能够显示0和“这有效”,然后因${testing2}
未设置而失败。
相反,我显示0和“这有效”, 遵从0进而0 这个不应该出现
谁能提供一些知识吗?谢谢。
答案1
来自“男人狂欢”:
如果参数已被赋值,则该参数被设置。空字符串是有效值。一旦设置了变量,就只能使用 unset 内置命令来取消设置。
当您这样做时,testing2=
您将变量设置为空字符串。
将其更改为unset testing2
并重试。
在这种情况下没有set -e
帮助,因为赋值永远不会有退出代码 1。尝试执行此操作以查看最后执行的命令(赋值)的退出代码为 0,或者阅读这个问题:
$ false; a=""; echo $?
0
而且我还相信 set -e 的使用更多的是一个问题而不是解决方案。
使用未设置的变量可能会出现错误set -u
:
#!/bin/bash
set -u
testing="This works"
echo ${testing}
unset testing2
echo ${testing2}
testing3="This should not appear"
echo ${testing3}
将输出:
$ ./script.sh
This works
./script.sh: line 9: testing2: unbound variable
答案2
testing2=
将变量设置testing2
为空字符串;变量实际上已设置。
echo $testing99
但是,如果您要在交互式 Bash shell 中运行(没有设置errexit
,即set -e
),您将收到错误:
bash: testing99: unbound variable
在旁边
刚才测试脚本时,我发现交互的壳 并不总是退出当试图扩展一个变量时尚未设置而一个非交互式shell(运行 shell 脚本)总是退出。根据 POSIX 手册页set
:
-u 当 shell 尝试扩展未设置的变量并立即退出时,它应向标准错误写入一条消息。交互式 shell 不应退出。
交互式 Bash shell 不会退出,errexit
除非还已设置。另一方面,交互式仪表板 shell 不会退出——即使set -e
之前已经运行过。