简短形式的if表现不同

时间:2018-04-13 07:47:55

标签: bash shell

在我的单元测试部分,我有一个脚本unit_runner.sh,它查找我的单元测试文件,获取它们并运行其中的每个测试函数。

  

unit_test_runner script

请注意,我的测试不应该写在标准输出

# ${test} contains the test function name
# So this runs a test, catch the error message if any
error_output=$(${test} 2>&1)
code=$?
# If the executed test does not return 0 or writes into stderr,
# consider it as failure
if [[ ${code} -ne 0 || ! -z ${error_output} ]]
then
     # error
fi
  

特定的测试功能   在一个测试函数中,我有:

test_do_something() {
    # the function I want to test

    result=do_something ${input}

    if [[ "${result}" = "fake output" ]]
    then
        exit 55
    fi
}

这很有效,这个测试通过了。我想按如下方式缩短它

 [[ "${result}" = "fake output" ]] && exit 55

这使我的测试失败。 AFAIK,这两种形式在行为方面完全相同。

怎么了?

1 个答案:

答案 0 :(得分:3)

问题是函数的退出代码是该函数中最后一个语句的退出代码。

如果条件为false,则if语句的退出代码为0:

$ if false; then echo false; fi
$ echo $?
0

但是如果我们使用短格式,结果就是整个表达式的退出代码。因为&&之前的部分评估为假(即1),所以第二部分没有执行,第一部分的结果成为整个表达式的退出代码:

$ false && echo false
$ echo $?
1

要解决此问题,您可以在函数末尾添加显式return 0exit 0,但这会违反速记符号的目的。

参考:bash联机帮助页。

  

[[ expression ]]

     

根据评估结果返回0或1的状态   条件表达式表达式。

     

...

     

if list; then list; [ elif list; then list; ] ... [ else list; ] fi

     

执行if列表。如果其退出状态为零,则执行then列表。否则,每个elif列表依次执行,如果其退出状态为零,则执行相应的then列表并执行命令                 完成。否则,执行else列表(如果存在)。退出状态是执行的最后一个命令的退出状态,如果没有条件测试为真,则为零。