我正在编写一个bash函数来检查空白或未设置的变量。
function exit_if_var_does_not_exist {
TMP_NAME=$1
TMP_VALUE=`echo $TMP_NAME`
if [ -z ${TMP_VALUE+x} ]; then
echo "Variable [${TMP_NAME}] is unset. Exiting."
exit 1
else
if [ ${TMP_VALUE} = "" ]; then
echo "Variable [${TMP_NAME}] is set to ''. Exiting."
exit 1
fi
fi
echo "Variable [${TMP_NAME}] is set to ${TMP_VALUE}"
}
VAR=Test
exit_if_var_does_not_exist VAR
BLANK=
exit_if_var_does_not_exist BLANK
这不会给我TMP_VALUE中的预期输出。有人可以帮我解决我在这里缺少的事情吗?
-bash-3.2$ ./x.sh
Variable [VAR] is set to VAR
Variable [BLANK] is set to BLANK
答案 0 :(得分:2)
空测试块的问题在于,此片段中的任何一点都没有实际获得最初命名变量的值。
当您使用TMP_NAME=$1
时,您将输入变量的名称分配给TMP_NAME
,然后
TMP_VALUE=`echo $TMP_NAME`
只需将该名称指定给TMP_VALUE
即可。实际上你刚刚运行了TMP_VALUE=$1
。
因此,您无法测试最初命名的变量是否包含此处的任何内容。
为此,您需要使用indirect expansion。
即TMP_VALUE=${!TMP_NAME}
或TMP_VALUE=${!1}
。
评论你的"未设置"顶部的测试块可以从不触发。
TMP_VALUE
可以从不取消设置,因为您已分配给它。即使TMP_VALUE=
也将变量标记为" set"。所以这一点毫无用处。虽然,并且感谢David C. Rankin尝试了足够长的时间让我想到这一点,但可以使用间接扩展技巧来实现这一目标。
[ -z "${!TMP_NAME+x}" ]
中指定的任何set变量, TMP_NAME
将返回true,对于未设置的变量,
: "${VAR:?Error VAR is unset or blank.}" || exit 1
将返回false。
如果变量未设置或空白,那么所有人都会说你想要做的是错误。只需使用
[
最后,正如David C. Rankin在-z
内部指出的那样,你需要引用当他们改变测试含义时可能会消失的扩展(你在上面的[ ${TMP_VALUE} = "" ]
测试中看到这一点)以及这里。
所以[ "${TMP_VALUE}" = "" ]
需要TMP_VALUE
因为[ = "" ]
为空,第一个版本会出现语法错误,因为test
不是{{}的有效调用1}} / [
。
答案 1 :(得分:2)
我不确定这适用于所有情况,但请尝试:
#!/bin/bash
function exit_if_var_does_not_exist {
local TMP_NAME=$1
local TMP_VALUE="${!TMP_NAME}"
[ -z "${!TMP_NAME}" ] && {
echo "Variable [${TMP_NAME}] is unset. Exiting."
return 1
}
[ "$TMP_VALUE" = "" ] && {
echo "Variable [${TMP_NAME}] is set to ''. Exiting."
return 1
}
echo "Variable [${TMP_NAME}] is set to ${TMP_VALUE}"
}
VAR=Test
exit_if_var_does_not_exist VAR
# BLANK=
exit_if_var_does_not_exist BLANK
<强>输出强>
$ bash tstempty.sh
Variable [VAR] is set to Test
Variable [BLANK] is unset. Exiting.
改进间接汤
在评论和建议中进行了一些讨论之后,我认为我的版本更加一致。再一次,我认为这是合格的,我不确定它是否适用于所有情况,但对于测试似乎:
#!/bin/bash
function exit_if_var_does_not_exist {
local TMP_NAME=$1
local TMP_VALUE="${!TMP_NAME}"
if ! declare -p $1 >/dev/null 2>&1 ; then
[ -z "${!TMP_NAME}" ] && {
echo "Variable [${TMP_NAME}] is unset. Exiting."
return 1
}
elif [ "$TMP_VALUE" = "" ]; then
echo "Variable [${TMP_NAME}] is set to ''. Exiting."
return 1
fi
echo "Variable [${TMP_NAME}] is set to ${TMP_VALUE}"
}
VAR=Test
exit_if_var_does_not_exist VAR
# BLANK=
exit_if_var_does_not_exist BLANK
EMPTY=""
exit_if_var_does_not_exist EMPTY
<强>输出强>
$ bash tstempty.sh
Variable [VAR] is set to Test
Variable [BLANK] is unset. Exiting.
Variable [EMPTY] is set to ''. Exiting.
答案 2 :(得分:1)
另一种方式:
exit_if_var_does_not_exist() {
if ! (set -u; : "${!1}") >/dev/null 2>&1; then
printf 'Variable [%s] is unset. Exiting.\n' "$1"
exit 1
elif [ -z "${!1}" ]; then
printf "Variable [%s] is set to ''. Exiting.\n" "$1"
exit 1
fi
printf 'Variable [%s] is set to %s\n' "$1" "${!1}"
}
如果您不需要分开两个错误消息:
exit_if_var_does_not_exist() {
: "${!1:?$1 is unset or blank}"
printf 'Variable [%s] is set to %s\n' "$1" "${!1}"
}