[英]Bash If-statement to check If string is equal to one of several string literals
In my bash script, I am checking that the first argument is either -
, 0
, or +
, using following if
statement: 在我的bash脚本中,我使用以下
if
语句检查第一个参数是-
, 0
还是+
:
LEVEL=$1
if [ "$LEVEL" -ne "-" ] && [ "$LEVEL" -ne "0" ] && [ "$LEVEL" -ne "+" ]
then
echo "The value of LEVEL must be either -, 0, or +!"
exit 1
fi
But it's giving me the error [: -: integer expression expected
, referring to the line with the if
statement conditions. 但这给了我错误
[: -: integer expression expected
,指的是带有if
语句条件的行。
I've been trying lots of different syntaxes (eg, double vs single brackets, quoting vs non-quoting the variables and string literals), but I can't figure it out. 我一直在尝试许多不同的语法(例如,双括号与单括号,引用与不引用变量和字符串文字),但我无法弄清楚。
The conventional approach, compatible with POSIX sh rather than leveraging bashisms, is to use the case
statement: 与POSIX sh兼容而不是利用bashisms的常规方法是使用
case
语句:
case $level in
-|0|+)
echo "Got it!" ;;
*)
echo "Not a valid value" ;;
esac
That said, if you wanted to use test
, you could do that too: 就是说,如果您想使用
test
,也可以这样做:
if [ "$LEVEL" != "-" ] && [ "$LEVEL" != "0" ] && [ "$LEVEL" != "+" ]; then
...
fi
!=
is the negating string comparison operator, and =
(not ==
) is the POSIX-compatible positive-matching one. !=
是负数字符串比较运算符,而=
(不是==
)是POSIX兼容的正匹配数。 (Bash extends POSIX to support ==
in test, but making a habit of using this extension will get you into trouble if you try to write code for a pure POSIX shell later). (Bash在测试中将POSIX扩展为支持
==
,但是养成使用此扩展的习惯会使您在以后尝试为纯POSIX shell编写代码时遇到麻烦)。
In a comment, a follow-up question was asked, in terms of whether the set of possible characters could be read from a variable. 在评论中,有人问了一个后续问题,即是否可以从变量中读取可能的字符集。 In general, yes, though there are some caveats:
通常,是的,尽管有一些警告:
# no spaces in possible_levels, as we're using it to form a pattern
possible_levels='-0+'
possible_levels_pattern="[${possible_levels}]"
if [[ $value = $possible_levels_pattern ]]; then
echo "value contains a valid level"
fi
...As an even shorter approach that allows your input string to be used unmodified, and is almost correct: ...作为一种更短的方法,允许您不修改输入字符串就使用它,并且几乎是正确的:
# caveat: will say some incorrect strings, like "- 0" or "0 +", are valid levels
possible_levels=' - 0 +'
check_level() {
[[ " $possible_levels " = *" $1 "* ]] && echo "Value is a valid level"
}
...or, as yet another implementation (verbose, but correct in the particulars): ...,或作为另一种实现方式(详细,但在细节上正确):
possible_levels=' - 0 +'
read -a possible_levels_array <<<"$possible_levels"
check_level() {
local possible_level
local value=$1
for possible_level in "${possible_levels_array[@]}"; do
[[ $value = "$possible_level" ]] && return 0
done
return 1
}
if check_level "$value"; then
echo "$value is a valid level"
else
echo "$value is not a valid level"
fi
Obviously, this is a lot of work, and in general, just hardcoding the comparisons when appropriate (and possible without a loss of safety) will save you trouble over trying to make things more generic than they truly need to be. 显然,这是很多工作,总的来说,仅在适当的时候对比较进行硬编码(并且可能会在不损失安全性的情况下),将使您避免尝试使事情变得比实际需要的更为通用。
Now, if we could pass in the variable as an associative array, without needing to support the silly space-separated-list thing, that makes it much shorter: 现在,如果我们可以将变量作为关联数组传递,而无需支持愚蠢的以空格分隔的列表,则它会变得更短:
declare -A possible_levels=( [-]=1 [+]=1 [0]=1 )
if [[ ${possible_levels[$value]} ]]; then
echo "valid level"
else
echo "invalid level"
fi
You can use [[ and ]]
use a selector: 您可以使用
[[ and ]]
使用选择器:
if [[ "$LEVEL" == [0+-] ]]; then
echo "got it"
fi
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.