Bash函数中的返回和退出的区别

Bash函数中的returnexit语句在退出代码方面有什么区别?

527394 次浏览

man bashreturn [n];

使函数停止执行并将n指定的值返回给调用者。如果省略n,返回状态为函数体中最后执行的命令。

... exit [n]:

使shell以状态n退出。如果省略n,退出状态为最后执行的命令。EXIT上的trap在shell终止之前执行。

编辑:

根据你对问题的编辑,关于退出码,return与退出码无关。退出码用于应用程序/脚本,而不是函数。因此,在这方面,唯一设置脚本退出码的关键字(可以被调用程序使用$? shell变量捕获的关键字)是exit

编辑2:

我的最后一个语句引用exit引起了一些评论。这样做是为了区分returnexit,以理解OP,事实上,在程序/shell脚本的任何给定点,exit是用调用进程的退出码结束脚本的唯一方法。

在shell中执行的每个命令都会产生一个本地“退出代码”:它将$?变量设置为该代码,并且可以与if&&和其他操作符一起有条件地执行其他命令。

这些退出码(以及$?变量的值)将在每次命令执行时重置。

顺便提一下,脚本执行的最后一个命令的退出码被用作调用进程看到的脚本本身的退出码。

最后,函数在被调用时,作为关于退出代码的shell命令。函数的退出码( The function)是通过使用return来设置的。因此,当在函数return 0中运行时,函数执行将终止,并给出退出码0。

return将导致当前函数超出作用域,而exit将导致脚本在调用它的地方结束。下面是一个示例程序来帮助解释这一点:

#!/bin/bash


retfunc()
{
echo "this is retfunc()"
return 1
}


exitfunc()
{
echo "this is exitfunc()"
exit 1
}


retfunc
echo "We are still here"
exitfunc
echo "We will never see this"

输出

$ ./test.sh
this is retfunc()
We are still here
this is exitfunc()

记住,函数是脚本内部的,通常使用return语句返回调用它们的地方。调用外部脚本完全是另一回事,脚本通常以退出语句结束。

Bash函数中返回语句和退出语句在退出代码方面的差异;非常小。两者都返回一个状态,而不是本身。状态为0表示成功,而任何其他状态(1到255)表示失败。返回语句将从调用它的地方返回到脚本,而exit语句将从遇到它的地方结束整个脚本。

return 0  # Returns to where the function was called.  $? contains 0 (success).


return 1  # Returns to where the function was called.  $? contains 1 (failure).


exit 0  # Exits the script completely.  $? contains 0 (success).


exit 1  # Exits the script completely.  $? contains 1 (failure).

如果函数结束时没有返回语句,则最后执行的命令的状态将作为状态代码返回(并将放置在$?中)。

记住,return和exit返回一个从0到255的状态码,在$?中可用。你不能把任何东西塞进状态码(例如,返回“cat");这是行不通的。但是,脚本可以通过使用状态码返回255个不同的失败原因。

你可以设置调用脚本中包含的变量,或者回声在函数中产生,并在调用脚本中使用命令替换;但是return和exit的目的是传递状态码,而不是像C这样的编程语言中所期望的值或计算结果。

我认为没有人真正完全回答了这个问题,因为他们没有描述这两者是如何使用的。好了,我想我们知道退出会终止脚本,无论它在哪里被调用,你也可以为它分配一个状态,比如退出或退出0或退出7等等。这可以用来确定如果被另一个脚本调用,脚本是如何被迫停止的,等等。退出说得够多了。

返回,当被调用时,将返回指定的值来指示函数的行为,通常是1或0。例如:

    #!/bin/bash
isdirectory() {
if [ -d "$1" ]
then
return 0
else
return 1
fi
echo "you will not see anything after the return like this text"
}

像这样检查:

    if isdirectory $1; then echo "is directory"; else echo "not a directory"; fi

或者像这样:

    isdirectory || echo "not a directory"

在本例中,可以使用测试来指示是否找到了目录。注意,返回之后的任何内容都不会在函数中执行。0在shell中为真,但false为1,这与其他编程语言不同。

有关函数的更多信息: Bash函数返回值 . bb0 . rref ="http://www.linuxjournal.com/content/return-values-bash-functions" rel="noreferrer">

请注意: isdirectory函数仅用于教学目的。这不应该是你在真正的脚本中执行这样的选项

有时,使用.source运行脚本。

. a.sh

如果你在a.sh中包含exit,它不仅会终止脚本,还会结束你的shell会话。

如果你在a.sh中包含return,它只是停止处理脚本。

简单来说(主要针对编程新手),我们可以说:

    `return`: exits the function,
`exit()`: exits the program (called as process while running)

还有如果你观察到,这是非常基本的,但是…,

    `return`: is the keyword
`exit()`: is the function

首先,return是一个关键字,exit是一个函数。

也就是说,这里有一个最简单的解释。

return

它从函数中返回一个值。

exit

它退出或放弃当前shell。

  • exit终止当前的过程;不管有没有退出码,都应该把它看作一个系统,而不是一个程序函数。注意,当采购时,exit将结束shell。然而,在运行时,它只会exit脚本。

  • return从函数返回到调用后的指令,带或不带返回码。return是可选的,在函数的末尾是隐式的。return只能在函数内部使用。

我想补充的是,在被引用的时候,在不杀死shell的情况下从函数中exit脚本是不容易的。我认为,“测试”脚本上的示例更好:

#!/bin/bash
function die(){
echo ${1:=Something terrible wrong happen}
#... clean your trash
exit 1
}


[ -f /whatever/ ] || die "whatever is not available"
# Now we can proceed
echo "continue"

做以下事情:

user$ ./test
Whatever is not available
user$

test - shell将关闭。

user$ . ./test
Whatever is not available

只有test将结束,并且将显示提示符。

解决方案是将潜在的过程包含在()中:

#!/bin/bash
function die(){
echo $(1:=Something terrible wrong happen)
#... Clean your trash
exit 1
}


( # Added
[ -f /whatever/ ] || die "whatever is not available"
# Now we can proceed
echo "continue"
) # Added

现在,在这两种情况下,只有test将退出。

OP的问题: BASH函数中的返回语句和退出语句在退出代码方面有什么区别?< / p >

首先,需要做一些澄清:

  • 一个(返回|exit)语句不需要终止一个(函数|shell)的执行。即使没有(return|exit)语句,函数|shell也会在到达代码列表的末尾时终止。

  • 一个(返回|exit)语句不需要从一个终止的(函数|shell)中返回一个值。每个进程都有一个内置变量$?,它总是有一个数值。它是一个特殊的变量,不能像"?=1"那样设置,但它只能以特殊的方式设置(见下面*)。

    $?在(被调用的函数|子shell)中执行的最后一个命令之后,是传递回(函数调用方|父shell)的值。无论最后执行的命令是(&;return [n]&;| &;exit [n]&;)还是普通的(&;return&;或者恰好是被调用函数代码中的最后一个命令。

在上面的项目列表中,选择"(x|y)"要么总是在第一项,要么总是在第二项,分别获取关于函数和return的语句,或者shell和exit。

很清楚的是,它们都使用特殊变量$?来在终止后向上传递值。

现在来看看$?的特殊设置方法:

  • 当一个被调用的函数终止并返回给它的调用者时,$?将等于终止函数中$?的最终值。
  • 当父shell隐式或显式地等待单个子shell并通过终止该子shell而释放时,则父shell中的$?将等于终止子shell中$?的最终值。
  • 一些内置函数可以根据结果修改$?。但有些则不然。
  • 内置功能“返回”;和"exit",当后面跟着一个数值参数时,都用它们的参数设置$?,并终止执行。

值得注意的是,$?可以通过在子shell中调用exit来赋值,如下所示:

# (exit 259)
# echo $?
3

如果将Bash脚本转换为函数,则通常将exit N替换为return N。调用该函数的代码将像对待子进程的退出代码一样对待返回值。

在函数中使用exit将强制整个脚本结束。

在其他一些答案中添加一个可操作的方面:

两者都可以给出退出代码- default或由函数定义,并且唯一的“default”是零,表示成功退出和返回。任何状态都可以有一个自定义数字0-255,包括成功。

Return通常用于在当前shell中运行的交互式脚本,例如用. script.sh调用,并将您返回到调用shell。然后返回代码可以被调用shell访问——$?会给你定义的返回状态。 在这种情况下,Exit也会关闭您的shell(包括SSH连接,如果这是您的工作方式)

如果脚本是可执行的,并且从另一个脚本或shell调用并且在子shell中运行,那么Exit是必要的。然后退出码可以被调用shell访问-在这种情况下return会给出一个错误。