Dav*_*veP 28 variables bash undefined
一个简单的Bash变量测试:
${varName:? "${varName} is not defined"}
Run Code Online (Sandbox Code Playgroud)
我想把它放在一个函数中来重复使用它.怎么样?
以下失败
#
# Test a variable exists
tvar(){
val=${1:? "${1} must be defined, preferably in $basedir"}
if [ -z ${val} ]
then
echo Zero length value
else
echo ${1} exists, value ${1}
fi
}
Run Code Online (Sandbox Code Playgroud)
即如果测试失败,我需要退出.
Pau*_*ce. 46
感谢lhunath的回答,我被引导到了Bash man
页面的一部分,我忽略了数百次:
When not performing substring expansion, bash tests for a parameter that is unset or null; omitting the colon results in a test only for a parame? ter that is unset.
这促使我创建以下真值表:
| unset | set | set and | meaning | | but null | not null | ============+=======+==========+==========+============================= ${var-_} | T | F | T | not null or not set ------------+-------+----------+----------+----------------------------- ${var:-_} | T | T | T | always true, use for subst. ------------+-------+----------+----------+----------------------------- $var | F | F | T | var is set and not null ------------+-------+----------+----------+----------------------------- ${!var[@]} | F | T | T | var is set
该表介绍了最后一行中的规范.Bash man
页面显示"如果name不是数组,如果设置了name,则展开为0,否则为null." 出于这个真值表的目的,即使它是一个数组,它的行为也是一样的.
lhu*_*ath 19
你正在寻找的是间接的.
assertNotEmpty() {
: "${!1:? "$1 is empty, aborting."}"
}
Run Code Online (Sandbox Code Playgroud)
如果您执行以下操作,则会导致脚本中止并显示错误消息:
$ foo=""
$ assertNotEmpty foo
bash: !1: foo is empty, aborting.
Run Code Online (Sandbox Code Playgroud)
如果您只想测试是否foo
为空,而不是中止脚本,请使用此代替函数:
[[ $foo ]]
Run Code Online (Sandbox Code Playgroud)
例如:
until read -p "What is your name? " name && [[ $name ]]; do
echo "You didn't enter your name. Please, try again." >&2
done
Run Code Online (Sandbox Code Playgroud)
另请注意,empty和unset参数之间存在非常重要的差异.你应该注意不要混淆这些条款!空参数是一个设置但只能设置为空字符串的参数.未设置的参数是根本不存在的参数.
前面的例子都测试了空参数.如果要测试未设置的参数并考虑所有设置的参数,无论它们是否为空,请使用以下命令:
[[ ! $foo && ${foo-_} ]]
Run Code Online (Sandbox Code Playgroud)
在这样的函数中使用它:
assertIsSet() {
[[ ! ${!1} && ${!1-_} ]] && {
echo "$1 is not set, aborting." >&2
exit 1
}
}
Run Code Online (Sandbox Code Playgroud)
只有在您传递的参数名称表示未设置的参数时才会中止脚本:
$ ( foo="blah"; assertIsSet foo; echo "Still running." )
Still running.
$ ( foo=""; assertIsSet foo; echo "Still running." )
Still running.
$ ( unset foo; assertIsSet foo; echo "Still running." )
foo is not set, aborting.
Run Code Online (Sandbox Code Playgroud)
你想用 [ -z ${parameter+word} ]
部分内容man bash
:
Parameter Expansion
...
In each of the cases below, word is subject to tilde expansion, parameter expansion, command substitution, and
arithmetic expansion. When not performing substring expansion, bash tests for a parameter that is unset or null;
omitting the colon results in a test only for a parameter that is unset.
...
${parameter:+word}
Use Alternate Value. If parameter is null or unset, nothing is substituted, otherwise the expansion of
word is substituted.
...
Run Code Online (Sandbox Code Playgroud)
换一种说法:
${parameter+word}
Use Alternate Value. If parameter is unset, nothing is substituted, otherwise the expansion of
word is substituted.
Run Code Online (Sandbox Code Playgroud)
一些例子:
$ set | grep FOOBAR
$ if [ -z "${FOOBAR+something}" ]; then echo "it is unset"; fi
it is unset
$ declare FOOBAR
$ if [ -z "${FOOBAR+something}" ]; then echo "it is unset"; fi
$ FOOBAR=
$ if [ -z "${FOOBAR+something}" ]; then echo "it is unset"; fi
$ FOOBAR=1
$ if [ -z "${FOOBAR+something}" ]; then echo "it is unset"; fi
$ unset FOOBAR
$ if [ -z "${FOOBAR+something}" ]; then echo "it is unset"; fi
it is unset
$
Run Code Online (Sandbox Code Playgroud)
即,如果测试失败我需要退出。
代码:
${varName:? "${varName} is not defined"}
Run Code Online (Sandbox Code Playgroud)
当不存在名为“varName”的变量时,将返回非零退出代码。最后一个命令的退出代码保存在$?
.
关于您的代码:
val=${1:? "${1} must be defined, preferably in $basedir"}
Run Code Online (Sandbox Code Playgroud)
也许它没有做你需要的事情。如果$1
未定义,则将"${1}"
不替换任何内容。也许您想使用字面上${1}
不进行替换的单引号。
val=${1:? '${1} must be defined, preferably in $basedir'
Run Code Online (Sandbox Code Playgroud)