外部脚本函数上的bash命令替换收到错误的退出状态

时间:2016-06-19 19:15:51

标签: bash shell command-substitution

此示例在Mac El Capitan上使用bash

进行了测试

main_script.sh:

  

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

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

external.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

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

1 个答案:

答案 0 :(得分:2)

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

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

请注意,这类似地适用于declareexport内置。

举一个简单的例子说明:

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

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

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

这种反直觉的行为差异可以解释为local / declare / export 内置而非部分内容 shell语法

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