2013-04-07 78 views
13

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

相应误差一起表示导致那些错误的行下面。

+0

我希望我的无知会被原谅:我是比较新的bash编程,其语法不像我见过的其他任何编程语言。 – 2013-04-07 21:12:06

回答

24

它必须是:

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

解释

比较整数必须使用这些运营商(从人测试复制):

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 

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

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

+0

+1的正确答案。 – 2013-04-07 21:36:58

0
  • 的空间都在[ ]表达强制性的,所以

    if [ $x == 3 ]; then

  • 你需要在变量sigill[ ]测试

2

对于第一个错误信息,删除美元符号$并且在e周围不允许有空格QUAL签署=

x=3 

对于第二错误消息,之后3

if [ $x -eq 3 ] 

作为@loentar正确地指出的那样,它必须是-eq插入空格并x之前美元符号$和一个空间和既不是=也不是==

1

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

变量使用印记这是在他们面前该$。许多shell脚本语言使用变量签名来帮助区分字符串和变量。

例如:

foo=foo_value 
echo foo foo $foo foo 

会打印:

foo foo foo_value foo 

注意引号不是必需的呼应字符串声明。Windows批处理外壳非常类似:

set foo = foo_value 
echo foo foo %foo% foo 

正如你所看到的,印记当变量是假设扩展使用,而不是当你定义它。这是因为Unix 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"被执行。

在伯恩风格炮弹像Kornshell和BASH的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 

注意,如果条款不是布尔声明。这是一个执行的实际命令。

某处在Unix的发展初期,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可以处理它们。

另一个问题是,为什么有壳两套不同的字符串和数字测试。这是因为字符串可能只包含数字,但不是真正的数字。例如,如果你做库存,你可能有一个零件号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 

通知再次壳扩张执行前的*回声命令。这是一个shell脚本和一个典型的编程语言之间的主要区别。壳第一确实膨胀(填环境变量,水珠替代,运行子命令),它实际上执行命令之前。

set -xv会告诉你什么命令正在执行,以及如何在执行之前shell命令扩展命令。做set +xv会关闭。玩这个,你很快就会明白壳更好一点。

相关问题