我如何知道是否在Bash中设置了变量?
例如,如何检查用户是否向函数提供了第一个参数?
function a {
# if $1 is set ?
}
我如何知道是否在Bash中设置了变量?
例如,如何检查用户是否向函数提供了第一个参数?
function a {
# if $1 is set ?
}
当前回答
总结
使用test-n“${var-}”检查变量是否为空(因此也必须定义/设置)。用法:如果测试-n“${var-}”;然后echo“var设置为<$var>”其他的echo“var未设置或为空”传真使用test-n“${var+x}”检查变量是否已定义/设置(即使它是空的)。用法:如果测试-n“${var+x}”;然后echo“var设置为<$var>”其他的echo“var未设置”传真
注意,第一个用例在shell脚本中更常见,这是您通常想要使用的。
笔记
此解决方案应适用于所有POSIX shell(sh、bash、zsh、ksh、dash)这个问题的其他一些答案是正确的,但对于没有shell脚本经验的人来说可能会感到困惑,所以我想提供一个TLDR答案,这对这些人来说是最不困惑的。
解释
要了解此解决方案的工作原理,您需要了解POSIX测试命令和POSIX外壳参数扩展(spec),因此让我们介绍了解答案所需的绝对基础知识。
测试命令计算表达式并返回true或false(通过其退出状态)。如果操作数是非空字符串,则运算符-n返回true。例如,test-n“a”返回true,而test-n“”返回false。现在,要检查变量是否为空(这意味着必须定义它),可以使用test-n“$var”。然而,一些shell脚本有一个选项集(set-u),它会导致对未定义变量的任何引用都会发出错误,因此如果未定义变量var,表达式$var将导致错误。要正确处理这种情况,必须使用变量扩展,如果未定义变量,它将告诉shell用替换字符串替换变量,从而避免上述错误。
变量扩展${var-}表示:如果变量var未定义(也称为“unset”),请用空字符串替换它。因此,如果$var不为空,test-n“${var-}”将返回true,这几乎总是您想要在shell脚本中检查的。如果$var未定义或不为空,则反向检查将是test-z“${var-}”。
现在进入第二个用例:检查变量var是否已定义,无论是否为空。这是一个不太常见的用例,稍微复杂一点,我建议您阅读莱昂内尔的伟大答案,以更好地理解它。
其他回答
我总是发现另一个答案中的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(以前为空或未设置)也将设置为“默认值”。
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
这是我每天使用的:
#
# Check if a variable is set
# param1 name of the variable
#
function is_set() { [[ $(eval echo "\${${1}+x}") ]]; }
这在Linux和Solaris以及Bash 3.0下运行良好。
$ myvar="TEST"
$ is_set myvar ; echo $?
0
$ myvar=
$ is_set myvar ; echo $?
0
$ unset myvar
$ is_set myvar ; echo $?
1
用于检查变量是否已声明/未设置的函数
包括空$array=()
以下函数测试给定名称是否作为变量存在
# The first parameter needs to be the name of the variable to be checked.
# (See example below)
var_is_declared() {
{ [[ -n ${!1+anything} ]] || declare -p $1 &>/dev/null;}
}
var_is_unset() {
{ [[ -z ${!1+anything} ]] && ! declare -p $1 &>/dev/null;}
}
通过首先测试变量是否已(未)设置,可以避免对声明的调用(如果不需要的话)。然而,如果$1包含空$array=()的名称,则调用声明将确保获得正确的结果传递给/dev/null的数据不多,因为只有在变量未设置或为空数组时才会调用declare。
该功能将在以下条件下进行测试:
a、 #未声明a=;#已声明a=“foo”;#已声明a=();#已声明a=(“”);#已声明取消设置a;#未声明a、 #未设置a=;#未设置a=“foo”;#未设置a=();#未设置a=(“”);#未设置取消设置a;#未设置
.
有关详细信息一个测试脚本可以看到我对“如何检查bash中是否存在变量?”问题的回答。备注:declare-p的类似用法,正如Peregring lk的答案所示,确实是巧合。否则我当然会把它归功于你!
使用[[-z“$var”]]是了解变量是否已设置的最简单方法,但选项-z无法区分未设置的变量和设置为空字符串的变量:
$ set=''
$ [[ -z "$set" ]] && echo "Set" || echo "Unset"
Unset
$ [[ -z "$unset" ]] && echo "Set" || echo "Unset"
Unset
最好根据变量的类型进行检查:env变量、参数或常规变量。
对于env变量:
[[ $(env | grep "varname=" | wc -l) -eq 1 ]] && echo "Set" || echo "Unset"
对于参数(例如,检查参数$5的存在):
[[ $# -ge 5 ]] && echo "Set" || echo "Unset"
对于正则变量(使用辅助函数,以优雅的方式实现):
function declare_var {
declare -p "$1" &> /dev/null
}
declare_var "var_name" && echo "Set" || echo "Unset"
笔记:
$#:提供位置参数的数量。declare-p:提供作为参数传递的变量的定义。如果它存在,则返回0,如果不存在,返回1并打印错误消息。&>/dev/null:在不影响其返回代码的情况下抑制declare-p的输出。