我如何知道是否在Bash中设置了变量?
例如,如何检查用户是否向函数提供了第一个参数?
function a {
# if $1 is set ?
}
我如何知道是否在Bash中设置了变量?
例如,如何检查用户是否向函数提供了第一个参数?
function a {
# if $1 is set ?
}
当前回答
使用[[-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的输出。
其他回答
要检查是否设置了变量,请执行以下操作:
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
对于那些希望在使用set-u的脚本中检查未设置或空的脚本:
if [ -z "${var-}" ]; then
echo "Must provide var environment variable. Exiting...."
exit 1
fi
常规[-z“$var”]检查将因var而失败;未绑定变量如果设置-u但[-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 | "" |
+--------------------+----------------------+-----------------+-----------------+
if [[ ${!xx[@]} ]] ; then echo xx is defined; fi