2

此示例在 Mac El Capitan 上使用 bash 进行了测试

main_script.sh:

注意: func_a 和 func_b 是相同的,除了output声明局部变量的那一行。

func_a () {
    local output
    output="$(./external.sh some_function)"
    if [ $? -eq 0 ];then
        echo "A zero result ($?) -> $output <- end"
    else
        echo "A other result ($?) -> $output <- end"
    fi
}

func_b () {
    local output="$(./external.sh some_function)"
    if [ $? -eq 0 ];then
        echo "B zero result ($?) -> $output <- end"
    else
        echo "B other result ($?) -> $output <- end"
    fi
}

func_a
func_b

外部.sh:

some_function () {
    echo "this is the output"
    return 1
}

"$@"

当我运行 main_script 时,输出是:

A other result (1) -> this is the output <- end
B zero result (0) -> this is the output <- end

出于什么原因,在与命令替换相同的行上声明局部变量会影响结果?这可能是一个错误还是我错过了什么?

4

1 回答 1

2

原因是$?infunc_b反映了local内置命令的成功,而不是命令替换 ( $(...))的成功。

如果分配在语法上是正确的,local则内置成功- 无论 RHS 上的任何命令替换是否失败

请注意,这类似地适用于declareandexport内置函数。

用一个简单的例子来说明:

declare output="$(false)"; echo $? # -> 0(!) - even though `false` obviously fails.

相比之下,如果不涉及内置函数- 在简单变量赋值的情况下 - 命令替换失败反映在$?

output="$(false)"; echo $? # -> 1(!) - simple assignment; $(...) exit code is reported

这种行为上的反直觉差异可以通过local//是内置函数而不是shell 语法declareexport的一部分来解释

作为 builtins(内置命令),它们被视为commands,并且命令应该通过它们自己的退出代码来指示它们的成功/失败;如前所述,在所述内置函数的情况下,语法正确的分配被认为是成功的——换句话说:如果可以分配某些东西——即使由于 RHS 上的命令替换失败而导致该东西是空字符串——内置函数成功了。

于 2016-06-19T19:58:54.237 回答