我如何知道是否在Bash中设置了变量?
例如,如何检查用户是否向函数提供了第一个参数?
function a {
# if $1 is set ?
}
我如何知道是否在Bash中设置了变量?
例如,如何检查用户是否向函数提供了第一个参数?
function a {
# if $1 is set ?
}
当前回答
您可以执行以下操作:
function a {
if [ ! -z "$1" ]; then
echo '$1 is set'
fi
}
其他回答
您可以执行以下操作:
function a {
if [ ! -z "$1" ]; then
echo '$1 is set'
fi
}
如果您希望测试变量是否绑定或未绑定,即使在启用了nounset选项后,这也能很好地工作:
set -o noun set
if printenv variableName >/dev/null; then
# variable is bound to a value
else
# variable is unbound
fi
总结
使用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是否已定义,无论是否为空。这是一个不太常见的用例,稍微复杂一点,我建议您阅读莱昂内尔的伟大答案,以更好地理解它。
以下是如何测试参数是否未设置、是否为空(“Null”)或是否设置了值:
+--------------------+----------------------+-----------------+-----------------+
| Expression | parameter | parameter | parameter |
| in script: | Set and Not Null | Set But Null | Unset |
+--------------------+----------------------+-----------------+-----------------+
| ${parameter:-word} | substitute parameter | substitute word | substitute word |
| ${parameter-word} | substitute parameter | substitute null | substitute word |
| ${parameter:=word} | substitute parameter | assign word | assign word |
| ${parameter=word} | substitute parameter | substitute null | assign word |
| ${parameter:?word} | substitute parameter | error, exit | error, exit |
| ${parameter?word} | substitute parameter | substitute null | error, exit |
| ${parameter:+word} | substitute word | substitute null | substitute null |
| ${parameter+word} | substitute word | substitute word | substitute null |
+--------------------+----------------------+-----------------+-----------------+
来源:POSIX:参数扩展:
在所有显示为“替换”的情况下,表达式将替换为显示的值。在所有显示为“assign”的情况下,参数都被指定该值,该值也会替换表达式。
要在操作中显示此内容,请执行以下操作:
+--------------------+----------------------+-----------------+-----------------+
| Expression | When FOO="world" | When FOO="" | unset FOO |
| in script: | (Set and Not Null) | (Set But Null) | (Unset) |
+--------------------+----------------------+-----------------+-----------------+
| ${FOO:-hello} | world | hello | hello |
| ${FOO-hello} | world | "" | hello |
| ${FOO:=hello} | world | FOO=hello | FOO=hello |
| ${FOO=hello} | world | "" | FOO=hello |
| ${FOO:?hello} | world | error, exit | error, exit |
| ${FOO?hello} | world | "" | error, exit |
| ${FOO:+hello} | hello | "" | "" |
| ${FOO+hello} | hello | hello | "" |
+--------------------+----------------------+-----------------+-----------------+
声明一个简单函数is_set,它使用Declare-p直接测试变量是否存在。
$ is_set() {
declare -p $1 >/dev/null 2>&1
}
$ is_set foo; echo $?
0
$ declare foo
$ is_set foo; echo $?
1