检查bash中的一个数字是否等于另一个数字[重复]

问题描述 投票:31回答:4

我一直在尝试比较Bash中的两个数字是否相等(如果相等,则打印一条消息,但是对于这个简单的程序,我收到一些奇怪的错误消息:

#!/bin/bash

fun2 (){
    $x = 3
    //#prog.sh: line 4: =: command not found
    if [x == 3]
        then 
    //#prog.sh: line 6: [x: command not found
            echo "It's 3!"
    fi
}
fun2

导致错误的行下方显示了相应的错误。

bash
4个回答
57
投票

必须是:

 if [ $x -eq 3 ]; then .....

如果您希望使用更具可读性和自我解释性的代码,请使用以下语法:

 if test $x -eq 3; then .....

解释

要比较整数,您必须使用这些运算符(从man测试复制):

   INTEGER1 -eq INTEGER2
          INTEGER1 is equal to INTEGER2

   INTEGER1 -ge INTEGER2
          INTEGER1 is greater than or equal to INTEGER2

   INTEGER1 -gt INTEGER2
          INTEGER1 is greater than INTEGER2

   INTEGER1 -le INTEGER2
          INTEGER1 is less than or equal to INTEGER2

   INTEGER1 -lt INTEGER2
          INTEGER1 is less than INTEGER2

   INTEGER1 -ne INTEGER2
          INTEGER1 is not equal to INTEGER2

运算符==和!=仅用于字符串比较。

有关信息:“ [”命令是系统“测试”命令的别名。


4
投票

Shell脚本并不是真的要成为一种完整的语言,它在很大程度上取决于其他外部命令的工作。

变量使用sigil,即在它们前面的$。许多Shell脚本语言使用变量信号来帮助区分字符串和变量。

例如:

foo=foo_value
echo foo foo $foo foo

将打印:

foo foo foo_value foo

请注意,对于字符串的echo语句,引号不是必需的。 Windows Batch外壳非常相似:

set foo = foo_value
echo foo foo %foo% foo

如您所见,sigil用于假定要扩展的变量,但不定义变量时使用。那是因为Unix外壳是智能外壳。他们甚至在执行命令行之前就对命令行进行调整。外壳程序将替换环境变量之前执行:

foo=bar
$foo="whose value is this"  #Note the dollar sign!
echo The value of foo is $foo
echo The value of bar is $bar

这将打印出来:

The value of foo is foo
The value of bar is whose value is this

如果使用set -xv命令,您会看到$foo="whose value is this"在执行之前已扩展为bar=whose value is this"

[在像Kornshell和BASH这样的Bourne风格的shell中,if语句不是您想的那样。 if命令执行该语句,如果该命令返回零值,则将选择if子句。例如:

cat "foo" > my_file       #Create a one line file with the string foo in it.
if grep -q "foo" my_file  #grep command will return a zero exit code if it finds foo
then
    echo "The string 'foo' is in file my_file"
fi

注意if子句不是布尔型语句。这是一个实际执行的命令。

在Unix开发的早期某个地方,创建了test命令。您可以进行man test并查看如何使用它。

test命令允许您执行此操作:

foo=3
bar=3
if test foo -eq bar
then
    echo "foo and bar are equal"
else
    echo "foo and bar are not equal"
fi

如果您这样做:

$ ls -li /bin/test /bin/[

您将发现实际上存在一个名为[的命令,并且是test命令的硬链接。创建该代码的目的是使if语句看起来更像是您在常规编程语言中将看到的if语句:

foo=3
bar=3
if [ foo -eq bar ]
then
    echo "foo and bar are equal"
else
    echo "foo and bar are not equal"
fi

与上述脚本完全相同,但是使用[而不是test

这说明了为什么在许多测试中都需要破折号

(这是test命令的参数,并且参数以破折号开头!)。它还说明了为什么在[]周围需要空格。这些是实际的Unix命令,并且Unix命令周围必须有空格,以便Shell可以处理它们。

另一个问题是为什么shell对字符串和数字进行两组不同的测试。这是因为字符串可能只包含数字,但实际上不是数字。例如,如果您进行库存管理,则零件编号可能为00101。从数字上讲,它们是相等的,但作为字符串,它们是两个不同的字符串。 Shell脚本无法知道。相反,您必须让Shell脚本知道它是数字比较还是字符串比较。

Perl有类似的问题,因为您没有将变量声明为数字或非数字:

                         Shell Script              Perl
Boolean Operator     Numeric     String     Numeric    String
===================  =======     ======     =======    ======
Equals                 -eq        =           ==         eq
Not Equals             -ne        !=          !=         ne
Greater Than           -gt        >           >          gt
Less Than              -lt        <           <          lt
Greater or Equals      -ge        >=          >=         ge
Less Than or Equals    -le        <=          <=         le

您可以尝试其他一些事情:

$ echo "*"    #Echos the asterisk
$ echo *      #No quotes: Prints all files in current directory

再次在执行echo

命令之前通知shell expands *。这是Shell脚本和典型编程语言之间的主要区别。在实际执行命令之前,shell首先进行扩展(填充环境变量,glob替换,运行子命令)。

set -xv将向您显示正在执行的命令,以及在执行之前shell如何对命令进行[[expands

。进行set +xv将关闭该功能。尝试一下,您很快就会对外壳有了更好的了解。

3
投票
对于第一个错误消息,删除美元符号$,等号=周围不允许有空格

2
投票
  • [[ ]表达式中的空格是必需的,所以
© www.soinside.com 2019 - 2024. All rights reserved.