首页 > 解决方案 > 如果存储在局部变量中,函数调用的退出代码将被忽略

问题描述

以下是示例场景:-

定义了一个示例函数,它正在回显一些文本,以及使用 return 设置一些退出代码。还有另一个脚本正在调用此函数。以下是简化代码:-

~/playground/octagon/bucket/test/sample $

pwd
/Users/mogli/playground/octagon/bucket/test/sample

~/playground/octagon/bucket/test/sample $

cat functions.sh
myfunc() {
    echo "This is output $1"
    return 3
}

~/playground/octagon/bucket/test/sample $

cat example.sh
. functions.sh

function example(){
    myfunc_out=$(myfunc $1); myfunc_rc=$?
    echo "myfunc_out is: $myfunc_out"
    echo "myfunc_rc is: $myfunc_rc"
}

example $1

~/playground/octagon/bucket/test/sample $

sh example.sh 44
myfunc_out is: This is output 44
myfunc_rc is: 3

现在,如果我对用于在 example.sh 中存储函数返回值和退出代码的变量使用局部变量,则退出代码不会正确出现。请在下面找到修改后的 example.sh :-

~/playground/octagon/bucket/test/sample $

cat example.sh
. functions.sh

function example(){
    local myfunc_out=$(myfunc $1); local myfunc_rc=$?
    echo "myfunc_out is: $myfunc_out"
    echo "myfunc_rc is: $myfunc_rc"
}

example $1

~/playground/octagon/bucket/test/sample $

sh example.sh 44
myfunc_out is: This is output 44
myfunc_rc is: 0

标签: bashshellexit-code

解决方案


当你写:

var=$(cmd)

的输出cmd分配给var(没有分词)并$?设置为返回的值cmd

当你写:

var=$(cmd1) cmd2

cmd1被执行并将其输出(没有分词)分配给var环境中的变量cmd2,然后执行。 $?设置为返回的值cmd2

当你写:

cmd1 var=$(cmd2)

cmd2执行时,字符串var=output of cmd2会进行分词并作为参数传递给cmd1,并$?设置为 . 返回的值cmd1。(在几乎所有情况下,您都希望禁止分词并改为 write cmd1 var="$(cmd2)",这将保证只传递一个参数。)

local是一个命令,并且local myfunc_out=$(myfunc $1)是第 3 种形式(有一个警告),所以它设置为 .$?返回的值local。请注意,如果 的输出myfunc $1包含空格,则不会进行分词。引用 manpage: Assignment statements may also appear as arguments to the alias, declare, typeset, export, readonly, and local builtin commands,因此字符串算作变量赋值并且不进行分词。

简而言之,local有一个退出值,它被用来设置$?

local可以使用:

local myfunc_out myfunc_rc
myfunc_out="$(myfunc $1)"; myfunc_rc=$?

请注意,双引号在这里并不是绝对必要的,因为分词不会发生在作业中,但使用它们绝对是一个好习惯。


推荐阅读