在bash中取消设置变量检查
Posted
技术标签:
【中文标题】在bash中取消设置变量检查【英文标题】:unset variable check in bash 【发布时间】:2014-09-03 21:26:45 【问题描述】:我声明了两个变量但未设置:
__var1=
__var2=
现在我将__var2
设置为具有一些价值:
__var2=1
当我尝试进行这样的检查时:
[ -z "$__var1" -a -z "$__var2" ] || echo "Both missing!"
我收到了这条消息Both missing!
。但这是不正确。
这是为什么呢?以及如何进行适当的检查,看看它们是否都丢失了?
【问题讨论】:
从bash
4.2 开始,您可以使用-v
来测试是否设置了变量,而-z
将在变量未设置或设置为空字符串时为真: -v __var1
(不是没有美元符号;-v
采用变量的名称,而不是变量扩展为的字符串)。
很高兴知道,但是在我的脚本中,我确实声明了我的变量,只是想知道它们是__var1=
还是__var1=something
。
只是声明它们就被认为是设置,这不是很奇怪吗?
你没有在 shell 中声明变量。为未设置的名称分配一个值(var=
和 var=""
是等效的;两者都将空字符串分配给var
)使其成为一个设置变量。换句话说,shell 中不存在没有值的变量。
foo=; [[ -v foo ]] && echo "foo is set"; [[ ! -v bar ]] && echo "bar is not set"
.
【参考方案1】:
如果用户想检查变量是否真的没有设置,而不仅仅是一个空值,你可以这样做:
$ A=1234
$ [[ -z $A+. ]] && echo "Variable is unset."
$ A=
$ [[ -z $A+. ]] && echo "Variable is unset."
$ unset A
$ [[ -z $A+. ]] && echo "Variable is unset."
Variable is unset.
在你的情况下可能是
[[ -z $__var1+. && -z $__var2+. ]] && echo "Both variables are unset!"
【讨论】:
当var
是一个集合变量时,$var+something
格式扩展为something
,否则没有。你可以试试echo
。
所以即使你做variable=
也被认为是设置?【参考方案2】:
@Dave Schweissguth's answer 很好地说明了您的代码的逻辑,但对于语法也有一些需要注意的地方:
[更新:问题的原始形式使用了诸如$__var1=
之类的赋值 - 这已被更正] 在 Bourne-like/POSIX-compatible shells 中,您不要在赋值一个值时使用$
前缀,只有在引用它时;因此,你的作业应该是:
__var1=
__var2= # or, later: __var2=1
您的问题被标记为bash
,因此最好的 bash 方式来编写您的可能是:
[[ -z $__var1 && -z $__var2 ]] && echo "Both missing!"
注意[[ ... ]]
rater 的使用比[ ... ]
的使用,这避免了将操作数双引号到-z
的需要。
[ -z "$__var1" ] && [ -z "$__var2" ] && echo "Both missing!"
【讨论】:
所以在[[
中,未设置的变量会自动替换为某些东西,这样-z
一元运算符就不会丢失它的操作数?
@branquito:是的,这是使用[[ ... ]]
的优势之一。
我想在那种情况下它会变成""
?
@branquito:粗略地说,是的。更准确地说,[[ ... ]]
条件句的解析不同于 [ ... ]
及其等价物test
:后者的解析方式类似于命令行,而[[ ... ]]
的解析方式更像传统编程语言:而不是扩展$__var1
首先,然后评估结果(与[ ... ]
/ test
一样),表达式被解析一次性,所以bash
知道那里有 一个操作数,即使未定义或为空。 (这有点投机,但我希望它足够接近真相——并且依靠它在实践中有效。)
有点意外,但-a
不符合 POSIX 标准吗? [[ ]]
btw 说得好。【参考方案3】:
您的代码显示“两个都不见了!”如果两个 (-a
) 变量都为空 (-z
) 不是真的 (||
)。如果这是真的,您想打印该消息。这样做:
[ -z "$__var1" -a -z "$__var2" ] && echo "Both missing!"
我不记得曾经见过没有 -z
或 -a
的 bash 或 test 版本(sh 使用什么来评估相同的表达式),所以据我所知,上述内容适用于任何类 Unix您可能会找到的系统。
【讨论】:
我一定是太累了,错过了这些东西:) Re-a
和 -o
:POSIX 确实 允许 使用它们,但发出以下 警告 (man.cx/test) - 强调我的:“在处理用户提供的输入时,脚本应该小心,因为这些输入可能会与主元素和运算符混淆。除非应用程序编写者知道所有产生脚本输入的情况,否则像:test "$1" -a "$2"
这样的调用应该写成:@987654331 @ 以避免在用户提供的值(例如 $1 设置为 '!' 和 $2 设置为空字符串时出现问题。[...] 考虑最大可移植性的地方 [...] [使用] test expr1 && test expr2
"以上是关于在bash中取消设置变量检查的主要内容,如果未能解决你的问题,请参考以下文章