[[ " stop start status " =~ " $2 " && (($#<3)) ]] || { echo "Usage $0 file_name command"; exit 1;}
Run Code Online (Sandbox Code Playgroud)
我经常使用上述解决方案来检查我的 Bash 脚本的输入范围。
现在我意识到扩展的算术表达式(())看起来像是在双括号内被抑制了[[]]。
为了说明问题:
a=start; n=1; [[ " stop start status " =~ " $a " && (($n<3)) ]] && echo ok || echo bad
ok
a=start; n=5; [[ " stop start status " =~ " $a " && (($n<3)) ]] && echo ok || echo bad
bad
# But:
a=start; n=100; [[ " stop start status " =~ " $a " && (($n<3)) ]] && echo ok || echo bad
ok
Run Code Online (Sandbox Code Playgroud)
上面的结果是错误的,因为如果将它们视为数字,则 n 不小于 3。这是正确的解决方案:
a=start; n=100; [[ " stop start status " =~ " $a " ]] && (($n<3)) && echo ok || echo bad
bad
a=start; n=1; [[ " stop start status " =~ " $a " ]] && (($n<3)) && echo ok || echo bad
ok
Run Code Online (Sandbox Code Playgroud)
Ini*_*ian 10
GNU bash 手册页[[..]]解释了操作符运行条件表达式和
根据条件表达式的计算返回
0或1的状态expression。表达式由以下Bash 条件表达式中描述的主要元素组成。
但是算术运算符不是内部支持的条件表达式(primaries)的一部分,[[..]]这意味着该表达式被迫作为字符串比较运行,即
(( $n < 3))
Run Code Online (Sandbox Code Playgroud)
是不是在算术上下文中运行,但只是作为普通词典(串)作为比较
[[ 100 < 3 ]]
Run Code Online (Sandbox Code Playgroud)
这将总是导致真实的,因为ASCII值1,0,0才出现3
但是[[..]]如果您使用-lt,则支持内部算术运算,-gt
arg1 OP arg2OP是一个
-eq,-ne,-lt,-le,-gt,或-ge。如果分别arg1等于、不等于、小于、小于或等于、大于或大于或等于arg2,则这些算术二元运算符返回 true 。
所以你把你的表达写成
a=start; n=100; [[ " stop start status " =~ " $a " && $n -lt 3 ]] && echo ok || echo bad
bad
Run Code Online (Sandbox Code Playgroud)
它会按预期工作。
或者即使你已经通过在前面,迫使算术表达式使用$前((..))和下面写它(注意,庆典不有记载的行为$((..))里面[[..]])。可能的预期行为是在计算 之前扩展算术表达式,[[..]]并且在字符串上下文中计算结果输出,因为[[ 0 ]]这意味着非空字符串。
a=start; n=5; [[ " stop start status " =~ " $a " && $(( $n < 3 )) ]] && echo ok || echo bad
Run Code Online (Sandbox Code Playgroud)
结果看起来仍然很糟糕,因为里面的算术表达式[[..]]分解为一元字符串而不是空的比较表达式
$(( 5 < 3 ))
0
[[ -n 0 ]]
Run Code Online (Sandbox Code Playgroud)
算术评估的结果0(false) 被测试运算符视为非零实体,并在 的右侧断言为真&&。这同样适用于另一种情况,例如说n=1
$(( 1 < 3 ))
1
[[ -n 1 ]]
Run Code Online (Sandbox Code Playgroud)
长话短说,在[[..]].
((是一个引入算术语句的“关键字”。[[但是,Inside不能使用其他语句。不过,您可以使用括号对表达式进行分组,这(( ... ))就是:一个冗余的“双组”。以下都是等价的,由于的优先级<和&&:
[[ " stop start status " =~ " $2 " && (($#<3)) ]][[ " stop start status " =~ " $2 " && ($#<3) ]][[ " stop start status " =~ " $2 " && $#<3 ]]如果您想要整数比较,请使用-lt代替<,但您也不需要将所有内容都放入[[ ... ]]. 您可以在命令列表中同时使用条件语句和算术语句。
{ [[ " stop start status " =~ " $2 " ]] && (($#<3)) ; } || { echo "Usage $0 file_name command"; exit 1;}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,... && ... || ...将按照您期望的方式工作,但通常情况并非如此。更喜欢if声明。
if [[ " stop start status " =~ " $2 " ]] && (($#<3)); then
echo "Usage $0 file_name command"
exit 1
fi
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
239 次 |
| 最近记录: |