我如何知道是否在Bash中设置了变量?
例如,如何检查用户是否向函数提供了第一个参数?
function a {
# if $1 is set ?
}
我如何知道是否在Bash中设置了变量?
例如,如何检查用户是否向函数提供了第一个参数?
function a {
# if $1 is set ?
}
当前回答
要检查是否设置了变量,请执行以下操作:
var=""; [[ $var ]] && echo "set" || echo "not set"
其他回答
我喜欢辅助功能来隐藏Bash的粗糙细节。在这种情况下,这样做会增加更多(隐藏的)粗糙度:
# The first ! negates the result (can't use -n to achieve this)
# the second ! expands the content of varname (can't do ${$varname})
function IsDeclared_Tricky
{
local varname="$1"
! [ -z ${!varname+x} ]
}
因为我在这个实现中首先遇到了bug(灵感来自Jens和Lionel的回答),所以我想出了一个不同的解决方案:
# Ask for the properties of the variable - fails if not declared
function IsDeclared()
{
declare -p $1 &>/dev/null
}
我发现它更直接,更害羞,更容易理解/记住。测试用例表明它是等效的:
function main()
{
declare -i xyz
local foo
local bar=
local baz=''
IsDeclared_Tricky xyz; echo "IsDeclared_Tricky xyz: $?"
IsDeclared_Tricky foo; echo "IsDeclared_Tricky foo: $?"
IsDeclared_Tricky bar; echo "IsDeclared_Tricky bar: $?"
IsDeclared_Tricky baz; echo "IsDeclared_Tricky baz: $?"
IsDeclared xyz; echo "IsDeclared xyz: $?"
IsDeclared foo; echo "IsDeclared foo: $?"
IsDeclared bar; echo "IsDeclared bar: $?"
IsDeclared baz; echo "IsDeclared baz: $?"
}
main
测试用例还显示,局部var不声明var(除非后面跟着“=”)。很长一段时间以来,我以为我是这样声明变量的,只是为了发现我只是表达了我的意图。。。我想这是不可能的。
IsDeclared_Tricky xyz:1IsDeclared_Tricky foo:1IsDeclared_Tricky条:0我声明的Tricky baz:0IsDeclared xyz:1IsDeclared foo:1IsDeclared栏:0IsDeclared baz:0
奖金:用例
我主要使用此测试以某种“优雅”和安全的方式(几乎类似于接口…)向函数提供(和返回)参数:
# Auxiliary functions
function die()
{
echo "Error: $1"; exit 1
}
function assertVariableDeclared()
{
IsDeclared "$1" || die "variable not declared: $1"
}
function expectVariables()
{
while (( $# > 0 )); do
assertVariableDeclared $1; shift
done
}
# Actual example
function exampleFunction()
{
expectVariables inputStr outputStr
outputStr="$inputStr, World!"
}
function bonus()
{
local inputStr='Hello'
local outputStr= # Remove this to trigger the error
exampleFunction
echo $outputStr
}
bonus
如果调用时声明了所有必需的变量:
你好,世界!
其他:
错误:未声明变量:outputStr
如果您希望测试变量是否绑定或未绑定,即使在启用了nounset选项后,这也能很好地工作:
set -o noun set
if printenv variableName >/dev/null; then
# variable is bound to a value
else
# variable is unbound
fi
if [ "$1" != "" ]; then
echo \$1 is set
else
echo \$1 is not set
fi
尽管对于参数,通常最好测试$#,我认为这是参数的数量。
if [ $# -gt 0 ]; then
echo \$1 is set
else
echo \$1 is not set
fi
如果你想检查$@中的任何内容,我找到了一个更好的代码。
if [[ $1 = "" ]] then echo '$1 is blank' else echo '$1 is filled up' fi
为什么会这样?$@中的所有内容都存在于Bash中,但默认情况下为空,因此test-z和test-n无法帮助您。
更新:您还可以计算参数中的字符数。
if [ ${#1} = 0 ] then echo '$1 is blank' else echo '$1 is filled up' fi
我总是发现另一个答案中的POSIX表很难找到,所以我的看法是:
parameter expansion | VARIABLE set |
VARIABLE empty |
VARIABLE unset |
---|---|---|---|
${VARIABLE-default} |
$VARIABLE |
"" |
"default" |
${VARIABLE=default} |
$VARIABLE |
"" |
$(VARIABLE="default") |
${VARIABLE?default} |
$VARIABLE |
"" |
exit 127 |
${VARIABLE+default} |
"default" |
"default" |
"" |
${VARIABLE:-default} |
$VARIABLE |
"default" |
"default" |
${VARIABLE:=default} |
$VARIABLE |
$(VARIABLE="default") |
$(VARIABLE="default") |
${VARIABLE:?default} |
$VARIABLE |
exit 127 |
exit 127 |
${VARIABLE:+default} |
"default" |
"" |
"" |
请注意,每个组(前面有和没有冒号)都有相同的设置和未设置的大小写,因此唯一不同的是如何处理空大小写。
对于前面的冒号,空的和未设置的大小写是相同的,因此我将在可能的情况下使用它们(即使用:=,而不仅仅是=,因为空的大小写不一致)。
标题:
set表示VARIABLE为非空(VARIABLE=“something”)空表示VARIABLE为空/空(VARIABLE=“”)未设置表示变量不存在(未设置变量)
值:
$VARIABLE表示结果是变量的原始值。“默认”表示结果是提供的替换字符串。“”表示结果为空(空字符串)。退出127意味着脚本停止执行,退出代码127。$(VARIABLE=“默认”)表示结果为“默认”,VARIABLE(以前为空或未设置)也将设置为“默认值”。