是 =、、==、!=、&& 和 ||用于算术表达式或条件表达式?

是 =、、==、!=、&& 和 ||用于算术表达式或条件表达式?

在 bash 手册中,第 6.5 节 Shell 算术说

<= >= < > comparison
== != equality and inequality 

&& logical AND
|| logical OR

它们的含义似乎暗示它们用于条件表达式。但它们出现在算术表达式部分。

  1. 那么它们可以用在条件表达式

    <=,>=,<,>,==,!=在 6.4 节中,我们已经有了条件表达式的运算符,它们与算术表达式类似:

    arg1 操作 arg2

    OP 是“-eq”、“-ne”、“-lt”、“-le”、“-gt”或“-ge”之一。如果 arg1 分别等于、不等于、小于、小于或等于、大于或大于或等于 arg2,这些算术二元运算符将返回 true。 Arg1和arg2可以是正整数或负整数。

    我们还已经有了条件表达式的运算符,它们类似于算术表达式的&&和:||

    • -a对于-otest[...]
    • &&||[[...]].

    既然我们已经为条件表达式引入了运算符,为什么我们还需要为算术表达式引入类似的运算符呢?

  2. 它们可以用于测试命令

    我们知道if后面是一个测试命令

    if 命令的语法为:

    if test-commands; then
    consequent-commands;
    [elif more-test-commands; then
    more-consequents;]
    [else alternate-consequents;]
    fi
    

    [...]两者[[...]]都采用条件表达式并创建测试命令。他们可以采用算术表达式吗?

    让我更加困惑的是,当它们中的算术[...]表达式[[...]]用作测试命令时,[...]行为不正确,而[[...]]正确:

    $ if [ 1 > 2 ]; then echo h; else echo b; fi
    h
    $ if [ 1 < 2 ]; then echo h; else echo b; fi
    h
    $ if [[ 1 < 2 ]]; then echo h; else echo b; fi
    h
    $ if [[ 1 > 2 ]]; then echo h; else echo b; fi
    b
    

答案1

这很简单。你只需要理解[][[]]并且(())作为完全不同的野兽。

[ expression ]只是程序的调用[(只是 的名称不同test),并将表达式作为参数,就像 bash 中的所有命令调用一样。这意味着,您必须在参数之间使用空格,尤其是 after[和 before ],并且关键字和特殊字符必须转义或引用,并且变量以通常的方式扩展。

在表达式中,-gt, -lt和 related 用于数值比较,而>, <和 sort 用于字符串比较。可以认为[与 bash 无关,只是调用一个计算表达式并返回 0(真)或非零(假)的命令,就像所有程序一样。

布尔运算符&&||不能在那里使用,因为它们由 bash 解释,而不是test作为参数传递。-a并被-o用来代替。但您始终可以执行[ test1 ] && [ test2 ] || [ test3 ],这是 3 个测试调用,由 的bash常用布尔运算符组合而成(也就是说,如果第一个失败,则跳过第二个)。

请注意,bash仍然带有它自己的[(builtin) 实现,但这并没有改变它的语法处理方式。

[[ ]](( ))不是命令的内置替代品,而是特殊语法的一部分,因此适用不同的规则。有关如何处理变量名通配符的详细信息,请参阅手册页。布尔运算符&&||具有通常的含义。

一种[[ ]]是以字符串为中心的:所有比较都是针对字符串的(但比 中更“现代”、更了解语言环境[,尽管test可能与平台相关)。它还处理文件测试、正则表达式等。

用于(( ))算术表达式。变量名称不需要$在那里,并且您通常可以在其中编写数学表达式 - 当然包括比较(数字)。这种情况下的比较与任何其他算术表达式没有什么不同,true 为 1,false 为 0,并且您可以编写类似(( x=y*(z>4) )).如果在条件表达式中使用,非零为真,零为假。您还可以将结果捕获为$(( )).

所以:

  • [[ ]]字符串条件、模式匹配和文件测试
  • (( ))算术表达式和条件
  • [ ]测试命令:处理布尔运算符和比较运算符的特殊非标准语法

答案2

“条件表达式”是test [or[[命令内部使用的内容。

所以,你的问题1和2的意思是一样的:

  1. 它们可以用在条件表达式中吗?:可以。
  2. 它们可以在测试命令中使用吗?:是的。

然而,它们并不意味着你的想法:

$ if [[ 1 < 2 ]]; then echo yes; else echo no; fi
yes
$ if [[ 10 < 2 ]]; then echo yes; else echo no; fi
yes
$ if [[ e < è ]]; then echo yes; else echo no; fi
yes

正如手册所述,这种比较:

True if string1 sorts before string2 lexicographically.

即:按字典顺序(并受 LC_COLLATE 变量的影响)

简单的测试[会将输出重定向到文件:

$ if [ e < è ]; then echo h; else echo b; fi
bash: è: No such file or directory
b

要使其正常工作,您需要使用反斜杠(引用 < 和 >):

$ if [ e \< è ]; then echo h; else echo b; fi
h

但我不建议在 中使用 < test


在其他可能使用 <、<=、>、>= 的地方是算术测试内部,这可能是 if 测试的一部分:

$ if (( 12 <= 15 )); then echo "yes"; fi
yes

是的,这相当于:

$ if [[ 12 -le 15 ]]; then echo "yes"; fi
yes

并且非常类似于:

$ if [ 12 -le 15 ]; then echo "yes"; fi
yes

所以,是的,这一切:

<= >= < >     comparison
== !=         equality and inequality 
&&            logical AND
||            logical OR

用于算术表达式中的条件表达式:

$ if (( ( ((2<3)&&(3>7)) * 18 ) == 0 )); then echo "yes"; fi
yes

这与命令中的条件表达式不同test

相关内容