检查一个数字是否等于bash中的另一个数字

时间:2013-04-07 21:06:34

标签: bash

我一直在尝试比较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

相应的错误显示在导致这些错误的行下面。

5 个答案:

答案 0 :(得分:40)

必须是:

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

<强>解释

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

   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

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

获取信息:“[”命令是系统“test”命令的别名。

答案 1 :(得分:3)

对于第一条错误消息,请移除美元符号$,等号周围不允许有空格=

x=3

对于第二条错误消息,请在$之前插入空格和美元符号x,在3之后插入空格

if [ $x -eq 3 ]

正如@loentar正确指出的那样,它必须是-eq,而===都不是。

答案 2 :(得分:3)

Shell脚本并不是真正的完整语言,它在很大程度上依赖于其他外部命令。

变量使用 sigil ,前面是$。许多shell脚本语言使用变量sigils来帮助区分字符串和变量。

例如:

foo=foo_value
echo foo foo $foo foo

将打印:

foo foo foo_value foo

请注意,字符串的 echo 语句不需要引号。 Windows Batch shell非常相似:

set foo = foo_value
echo foo foo %foo% foo

如您所见,当假设要扩展变量时使用 sigil ,但在定义变量时则不使用 sigil 。那是因为Unix shell是智能shell。他们甚至在执行命令之前就把它命中。 shell将在执行之前替换环境变量

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"已扩展为if

在像Kornshell和BASH这样的Bourne样式shell中,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子句。例如:

test

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

在Unix开发早期的某个地方,创建了test命令。您可以进行 man 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命令的硬链接。这是为了使foo=3 bar=3 if [ foo -eq bar ] then echo "foo and bar are equal" else echo "foo and bar are not equal" fi 语句看起来更像是在常规编程语言中看到的if语句:

[

与上述内容完全相同,但使用test代替test

这解释了为什么在许多测试中需要破折号(它是[命令的参数,参数以破折号开头!)。它还解释了为什么您需要]001周围的空格。这些是实际的Unix命令,Unix命令必须在它们周围有空格,因此shell可以处理它们。

另一个问题是为什么shell有两组不同的字符串和数字测试。那是因为字符串可能只包含数字,但实际上不是数字。例如,如果您执行广告资源,则可能包含部件号01 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 。在数字上,它们是相同的,但作为字符串,它们是两个不同的字符串。 shell脚本无法知道。相反,您必须让shell脚本知道它是数字比较还是字符串比较。

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

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

您可以尝试其他一些方法:

*

在执行 echo 命令之前,再次注意shell 扩展 set -xv。这是shell脚本和典型编程语言之间的主要区别。在实际执行命令之前,shell首先进行扩展(填充环境变量,全局替换,运行子命令)。

set +xv将显示正在执行的命令,以及shell 在执行之前如何扩展命令。执行{{1}}会关闭它。玩弄它,你很快就会更好地理解外壳。

答案 3 :(得分:2)

  • 空格在[ ]表达式中是必需的,所以

    if [ $x == 3 ]; then

  • [ ]测试中需要sigill个变量

答案 4 :(得分:0)

为了清楚起见,使用 == 表示相等而不是 =,即使两者都有效。前者鼓励使用 [[,后者可能与赋值混淆。使用 (( … ))-lt-gt 进行数值比较。

if [[ "${my_var}" == "val" ]]; then
  do_something
fi

if (( my_var == 3 )); then
  do_something
fi

if [[ "${my_var}" -gt 3 ]]; then
  do_something
fi