一个简单的Bash变量测试:
${varName:? "${varName} is not defined"}
我想通过把它放在一个函数中来重复使用它。 怎么样?
以下失败
#
# 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
}
即。如果测试失败,我需要退出。
答案 0 :(得分: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。”出于这个真值表的目的,即使它是一个数组,它的行为也是一样的。
答案 1 :(得分:19)
你正在寻找的是间接的。
assertNotEmpty() {
: "${!1:? "$1 is empty, aborting."}"
}
如果您执行以下操作,则会导致脚本中止并显示错误消息:
$ foo=""
$ assertNotEmpty foo
bash: !1: foo is empty, aborting.
如果您只想测试 foo
是否为空,而不是中止脚本,请使用此代替函数:
[[ $foo ]]
例如:
until read -p "What is your name? " name && [[ $name ]]; do
echo "You didn't enter your name. Please, try again." >&2
done
另请注意,空和未设置参数之间存在非常重要的差异。你应该注意不要混淆这些条款!空参数是一个设置但只能设置为空字符串的参数。未设置的参数根本不存在。
前面的示例全部测试空参数。如果您要测试未设置参数并考虑所有设置参数,无论它们是否为空,请使用以下命令:
[[ ! $foo && ${foo-_} ]]
在这样的函数中使用它:
assertIsSet() {
[[ ! ${!1} && ${!1-_} ]] && {
echo "$1 is not set, aborting." >&2
exit 1
}
}
只有在您传递的参数名称表示未设置的参数时才会中止脚本:
$ ( 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.
答案 2 :(得分:5)
您想使用[ -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.
...
换句话说,:
${parameter+word}
Use Alternate Value. If parameter is unset, nothing is substituted, otherwise the expansion of
word is substituted.
一些例子:
$ 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
$
答案 3 :(得分:3)
此函数测试当前设置的变量。变量甚至可以是一个数组。请注意,在bash中:0 == TRUE,1 == FALSE。
function var.defined {
eval '[[ ${!'$1'[@]} ]]'
}
# Typical Usage of var.defined {}
declare you="Your Name Here" ref='you';
read -p "What's your name: " you;
if var.defined you; then # Simple demo using literal text
echo "BASH recognizes $you";
echo "BASH also knows a reference to $ref as ${!ref}, by indirection.";
fi
unset you # have just been killed by a master :D
if ! var.defined $ref; then # Standard demo using an expanded literal value
echo "BASH doesn't know $ref any longer";
fi
read -s -N 1 -p "Press any key to continue...";
echo "";
所以在这里要清楚,该函数测试文字文本。每次在bash中调用命令时,变量通常被“换出”或“替换”基础值,除非:
答案 4 :(得分:1)
我并不完全明白你需要什么。尽管如此,我还是想回复你。
即。如果测试失败,我需要退出。
代码:
${varName:? "${varName} is not defined"}
当没有名为“varName”的变量时,将返回非零退出代码。最后一个命令的退出代码保存在$?
。
关于您的代码:
val=${1:? "${1} must be defined, preferably in $basedir"}
也许它没有做你需要的。在未定义$1
的情况下,"${1}"
将被替换为空。可能你想要使用单引号写字${1}
而无需替换。
val=${1:? '${1} must be defined, preferably in $basedir'
答案 5 :(得分:1)
不确定这是否正是你想要的,但我在编写新的+复杂脚本时使用的一个方便的技巧是使用“set -o”
set -o #will会在找到未设置的变量
时弹出脚本炸弹
EG:
$ grep'$ 1'chex.sh
中的案例“$ 1”
$ ./chex.sh
./ chex.sh:line 111:$ 1:未绑定的变量
$ ./chex.sh foo
错误/没有选项传递..退出
答案 6 :(得分:0)
if set | grep -q '^VARIABLE='
then
echo VARIABLE is set
fi