设置-u用法未按预期工作


12

我正在学习如何set在脚本中有效使用不同的选项,并且发现set -u如果变量未正确设置(例如删​​除用户),退出脚本似乎是完美的选择。根据手册页,set -uset -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“ This works”,然后由于${testing2}未设置而失败。

取而代之的是,我显示0,然后显示“这有效”,接着是0,然后是0, 这不应出现

谁能提供一些知识?谢谢。


1
所以跟进...有什么方法可以使将变量设置为空字符串非法/引发错误?我猜不是。
卢克·戴维斯

Answers:


10

来自“ man Bash”:

如果已为参数分配了值,则设置该参数。空字符串是有效值。设置变量后,只能使用unset Builtin内置命令将其取消设置。

执行此操作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

3

testing2=testing2变量设置为空字符串;该变量实际上已设置

但是,如果要echo $testing99在交互式Bash Shell中运行(不设置errexit,即set -e),则会出现错误:

bash: testing99: unbound variable

在旁边

虽然刚才的测试脚本,我发现了一个交互式的外壳 并不总是退出试图展开变量时尚未设置非交互式壳(运行shell脚本)总是退出。根据POSIX手册页的内容set

-u外壳程序在尝试扩展未设置的变量并立即退出时,应将消息写入标准错误消息。交互式外壳不得退出。

一个交互式的Bash shell不会退出,除非errexit被设置。另一方面,交互式破折号外壳不会退出-即使set -e以前已经运行过。


如果破折号没有通过set -e退出;设置-u; 未设置 回显$ aa,然后破折号是错误的。
schily

@schily当我第一次注意到这一点时,我发现破折号的作者比我了解得更多,并且POSIX规范中可能存在一些歧义,但是重新检查了pubs.opengroup.org/onlinepubs/9699919799/utilities/…,我同意看起来像个错误,好的。
Anthony Geoghegan

有一个简单的规则:当Korn Shell和Bourne Shell都同意并且另一个Shell实现存在偏差时,另一个Shell的行为将不正确。
schily
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.