我有一个变量可以采用任何值"SUBSCRIPT"
, "ITERATE"
, "COUNTER"
。
如何测试其中任何一个中的变量,并"SUBSCRIPT"
在不匹配的情况下默认为?
我想要一个紧凑的形式并提出了以下内容
[[ "${signal}" == "SUBSCRIPT" || "${signal}" == "ITERATE" ||
"${signal}" == "COUNTER" ]] || signal="SUBSCRIPT"
前面提到的会失败吗?
答案1
虽然你的代码应该工作,有几种可以说更简洁的方法来编写相同类型的操作。
第一种方法可以在任何 POSIX shell 中工作并使用标准case
语句:
case $signal in
SUBSCRIPT|ITERATE|COUNTER)
# do nothing
;;
*)
signal=SUBSCRIPT
esac
该case
语句将变量的值设置为字符串,SUBSCRIPT
除非它已经具有三个值之一SUBSCRIPT
,ITERATE
或COUNTER
。
您可以将其写在一行上,如下所示:
case $signal in (SUBSCRIPT|ITERATE|COUNTER) ;; (*) signal=SUBSCRIPT; esac
您还可以if
在以下位置使用更紧凑的语句bash
:
if [[ $signal != @(SUBSCRIPT|ITERATE|COUNTER) ]]; then
signal=SUBSCRIPT
fi
或者,如果适用,使用短路评估,
[[ $signal == @(SUBSCRIPT|ITERATE|COUNTER) ]] || signal=SUBSCRIPT
这使用扩展的通配模式来测试变量的值是否与提到的三个值中的任何一个匹配(语法是从 shell 继承的ksh
)。如果它不match (测试在代码的第一个变体中被反转,我||
在第二个变体中使用),变量的值被重置为 string SUBSCRIPT
。
答案2
对于仅三个有效值,现有答案提供了很好的方法。随着数量的增加,这可能会派上用场:
signal=foo
default='SUBSCRIPT'
if [ -n "$signal" ]; then
valid_values=(
SUBSCRIPT ITERATE COUNTER
)
declare -A tmpar=()
for str in "${valid_values=[@]}"; do
tmpar[$str]=1
done
test -n "${tmpar["$signal"]}" || signal="$default"
else
signal="$default"
fi
答案3
SUBSCRIPT
如果您的意思是希望变量在未设置/为空时被赋予以下值:
ITERATE=${ITERATE:-$SUBSCRIPT}