在我的bash脚本中,我使用以下-
语句检查第一个参数是0
,+
还是if
:
LEVEL=$1
if [ "$LEVEL" -ne "-" ] && [ "$LEVEL" -ne "0" ] && [ "$LEVEL" -ne "+" ]
then
echo "The value of LEVEL must be either -, 0, or +!"
exit 1
fi
但是它给了我错误[: -: integer expression expected
,引用了if
语句条件的行。
我一直在尝试许多不同的语法(例如,double vs single bracket,引用vs非引用变量和字符串文字),但我无法弄明白。
答案 0 :(得分:15)
与POSIX sh兼容而不是利用bashisms的传统方法是使用case
语句:
case $level in
-|0|+)
echo "Got it!" ;;
*)
echo "Not a valid value" ;;
esac
那就是说,如果你想使用test
,你也可以这样做:
if [ "$LEVEL" != "-" ] && [ "$LEVEL" != "0" ] && [ "$LEVEL" != "+" ]; then
...
fi
!=
是否定字符串比较运算符,而=
(不是==
)是与POSIX兼容的正匹配运算符。 (Bash在测试中扩展了POSIX以支持==
,但是如果你稍后尝试为纯POSIX shell编写代码,那么习惯使用这个扩展会让你遇到麻烦。
在评论中,根据是否可以从变量中读取可能的字符集,询问了后续问题。总的来说,是的,虽然有一些警告:
# 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
...作为一种更短的方法,允许您的输入字符串未经修改地使用,并且几乎正确:
# 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"
}
......或者,作为另一种实施方式(详细,但在详情中是正确的):
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
显然,这需要做很多工作,而且一般来说,只需在适当的时候对比较进行硬编码(并且可能不会失去安全性),这样可以避免在尝试使事物变得更加通用时遇到麻烦。 / p>
现在,如果我们可以将变量作为关联数组传递,而不需要支持愚蠢的空格分隔列表,那么它会缩短它:
declare -A possible_levels=( [-]=1 [+]=1 [0]=1 )
if [[ ${possible_levels[$value]} ]]; then
echo "valid level"
else
echo "invalid level"
fi
答案 1 :(得分:6)
您可以使用[[ and ]]
使用选择器:
if [[ "$LEVEL" == [0+-] ]]; then
echo "got it"
fi