Bash 如果存储在局部变量中,则忽略函数调用的退出代码

Bash 如果存储在局部变量中,则忽略函数调用的退出代码,bash,shell,exit-code,Bash,Shell,Exit Code,下面是示例场景:- 定义了一个示例函数,该函数回显一些文本,并使用return设置一些退出代码。还有另一个脚本正在调用此函数。以下是简化代码:- ~/playground/octagon/bucket/test/sample $ pwd /Users/mogli/playground/octagon/bucket/test/sample ~/playground/octagon/bucket/test/sample $ cat functions.sh myfunc() { ech

下面是示例场景:-

定义了一个示例函数,该函数回显一些文本,并使用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中用于存储函数返回值和退出代码的变量使用local,那么退出代码就不会正确出现。请查看下面修改的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
当你写作时:

var=$(cmd)
var=$(cmd1) cmd2
cmd
的输出被分配给
var
(无分词),并且
$?
被设置为
cmd
返回的值

当你写作时:

var=$(cmd)
var=$(cmd1) cmd2
执行
cmd1
,并在
cmd2
环境中将其输出(无分词)分配给变量
var
,然后执行该变量
$?
设置为
cmd2
返回的值

当你写作时:

var=$(cmd)
var=$(cmd1) cmd2
cmd1变量=$(cmd2)

执行
cmd2
,字符串
var=cmd2
的输出进行分词并作为参数传递给
cmd1
,并且
$?
设置为
cmd1
返回的值。(在几乎所有情况下,您都希望禁止分词,而是写入
cmd1 var=“$(cmd2)”
,这将保证只传递一个参数。)


local
是一个命令,
local myfunc\u out=$(myfunc$1)
是第三种形式(带有警告),因此它将
$?
设置为
local
返回的值。请注意,如果
myfunc$1
的输出包含空格,则不会进行分词。引用手册页:
赋值语句也可能显示为别名、声明、排版、导出、只读和本地内置命令的参数
,因此字符串将计为变量赋值,不会进行分词

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

您可以使用以下命令,而不是将赋值作为
local
的参数:

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

请注意,双引号在这里不是绝对必要的,因为在赋值中不进行分词,但使用双引号绝对是一种好的做法。

local
是一个具有自身退出状态的命令,而不是变量赋值语法的一部分。