【问题标题】:Why equal to operator does not work if it is surrounded by space?如果没有被空格包围,为什么等于运算符不起作用?
【发布时间】:2011-06-26 00:43:00
【问题描述】:

我尝试了以下脚本

#!/bin/bash
var1="Test 1" 
var2="Test 2"
if [ "$var1"="$var2" ] 
  then 
    echo "Equal" 
  else 
    echo "Not equal"
fi

它给了我Equal。虽然它应该打印Not equal

只有当我在 = 周围插入空格时,它才能按预期工作

if [ "$var1" = "$var2" ] 

并打印Not equal

为什么会这样?为什么"$var1"="$var2""$var1" = "$var2" 不一样?

而且,当我写if [ "$var1"= "$var2" ]时,它给了

line 4: [: Test 1=: unary operator expected

这是什么意思?它的期望一元运算符是怎么来的?

【问题讨论】:

    标签: bash shell syntax scripting


    【解决方案1】:

    test(或[ expr ])是一个内置函数。像 bash 中的所有函数一样,您将它的参数作为空格分隔的单词传递。

    正如 bash 内置函数的手册页所述:“每个运算符和操作数必须是单独的参数。”

    这正是 bash 和大多数其他 Unix shell 的工作方式。

    变量赋值不同。

    在 bash 中,变量赋值的语法为:name=[value]。您不能在 = 周围放置未加引号的空格,因为 bash 不会将其解释为您想要的分配。 bash 将大多数单词列表视为带有参数的命令。

    例如

    # call the command or function 'abc' with '=def' as argument
    abc =def
    
    # call 'def' with the variable 'abc' set to the empty string
    abc= def
    
    # call 'ghi' with 'abc' set to 'def'
    abc=def ghi
    
    # set 'abc' to 'def ghi'
    abc="def ghi"
    

    【讨论】:

    • 感谢查尔斯·贝利。还有一件事,正如手册页所说的“每个操作员和....”那么为什么var = "test" ; 不起作用?为了使它工作,我必须删除空格var="test"; Is assignment = is not an operator?
    • 该手册页适用于 test 内置函数。在 bash 中,变量赋值是 shell 语法的一部分,它不是函数。它不需要空格。
    • ...and 'abc = def' 使用两个参数 '=' 和 'def' 调用命令 abc
    【解决方案2】:

    当 shell 读取时

    如果 [ "$var1" = "$var2" ]

    它使用 4 个参数调用命令 [。 [ 是内置命令还是外部命令无关紧要,但它可能有助于理解它可能是外部命令 /bin/[。第二个参数是文字'=',第四个是']'。但是,当 shell 读取时

    如果 [ "$var1"="$var2" ]

    [ 只得到 3 个参数:$var1 的扩展加上 '='、$var2 的扩展和 ']'。当它只有 3 个参数时,它期望最后一个参数是 ']' 而第一个参数是一元运算符。

    【讨论】:

      【解决方案3】:

      为了补充现有的解释,"$var1"="$var2" 只是一个非空字符串,因此在条件中总是评估为真。

      [ "$var1"="$var2" ] && echo true
      

      上述命令将始终打印出true(即使var1var2 为空)。

      【讨论】:

        【解决方案4】:

        在 bash 中最好使用 [[ ]]:

        x="test"
        y="test"
        if [[ "${x}" = "${y}" ]]; then
            echo "Equals"
        else
            echo "No equals"
        fi
        

        【讨论】:

        • Bash[[ 由与所有其他结构相同的 shell 语法管理。切换到[[ 不会解决 OP 的问题。至于这是否“更好”取决于您是否优先考虑方便性而不是便携性。如果您致力于仅使用 Bash,那可能是真的。
        • 正如我所写的,我的意思是 bash。当然如果你希望你的代码是可移植的,你应该使用 /bin/sh
        • 不过,这并没有试图解决 OP 的问题,而是应该作为评论发布(如果有的话)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-11
        • 1970-01-01
        • 2015-07-06
        • 1970-01-01
        相关资源
        最近更新 更多