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

问题描述 投票:368回答:9

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

bash function return-value return exit
9个回答
274
投票

来自man bashreturn [n];

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

......在exit [n]上:

导致shell退出状态为n。如果省略n,则退出状态是最后执行的命令的状态。在shell终止之前执行EXIT上的陷阱。

编辑:

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

编辑2:

我上次提到exit的声明引起了一些评论。它是为了区分returnexit来理解OP,事实上,在程序/ shell脚本的任何给定点,exit是用调用进程的退出代码结束脚本的唯一方法。

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

每个命令执行都会重置这些退出代码(以及$?变量的值)。

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

最后,函数在被调用时,作为退出代码的shell命令。函数的退出代码(在函数内)使用return设置。因此,当运行return 0函数时,函数执行终止,退出代码为0。


267
投票

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"

Output

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

49
投票

我认为没有人真正完全回答这个问题,因为他们没有描述如何使用这两个问题。好吧我想我们知道退出会杀死脚本,无论它在哪里被调用,你也可以为它分配状态,例如退出或退出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为true但shell中的false为1,与其他prog langs不同。

有关函数的更多信息:http://www.linuxjournal.com/content/return-values-bash-functions

注意:isdirectory功能仅用于指导目的。这不应该是您在真实脚本中执行此类选项的方式。


29
投票

请记住,函数是脚本的内部函数,通常使用return语句从它们调用它们。调用外部脚本完全是另一回事,脚本通常以exit语句终止。

BASH函数中的返回和退出语句与退出代码之间的差异非常小。两者都返回状态,而不是值本身。状态为零表示成功,而任何其他状态(1到255)表示失败。 return语句将返回到调用它的脚本,而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语句结束,则执行的最后一个命令的状态将作为状态代码返回(并将放在$?中)。

请记住,return和exit将返回0到255之间的状态代码,可在$?中找到。你不能把任何东西塞进状态代码(例如返回“cat”);不起作用。但是,脚本可以使用状态代码传回255种不同的失败原因。

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


21
投票

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

. a.sh

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

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


6
投票

简单来说(主要是编码中的新手),我们可以说,

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

另外如果你观察到,这是非常基本的,但......

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

5
投票
  • exit终止当前进程;有或没有退出代码,考虑这个系统不仅仅是一个程序功能。请注意,在采购时,exit将结束shell,但是,运行时只会exit脚本。
  • 来自函数的return返回调用后的指令,带或不带返回码。 return是可选的,它隐含在函数的末尾。 return只能在函数内部使用。

我想在源代码时添加它,在一个函数中exit脚本并不容易,而不会杀死shell。我想,一个例子在'测试'脚本上更好

#!/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 - 并且 - 壳将关闭。

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将退出。


2
投票

OP的问题:BASH函数中的return和exit语句与退出代码有什么区别?

事实上,需要做出一些澄清:

  • 终止(函数| shell)的执行不需要(return | exit)语句。 A(函数| shell)将在到达其代码列表末尾时终止,即使没有(return | exit)语句也是如此。
  • 从终止(函数| shell)传递值不需要(return | exit)语句。每个进程都有一个内置变量$?它总是有一个数值。它是一个特殊变量,不能设置为“?= 1”,但只能以特殊方式设置(见下面的*)。 $的价值?在(调用函数|子shell)中执行的最后一个命令之后是传递回(函数调用者|父shell)的值。无论执行的最后一个命令是(“return [n]”|“exit [n]”)还是plain(“return”或其他恰好是被调用函数代码中的最后一个命令的东西)都是如此。

在上面的项目符号列表中,选择“(x | y)”或者始终是第一项,或者总是第二项来获取有关函数和return或者shell和exit的语句。

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

*现在以$?的特殊方式?可以设置:

  • 当一个被调用的函数终止并返回它的调用者然后$?在调用者中将等于$的最终值?在终止的功能中。
  • 当父shell隐含地或显式地等待单个子shell并且通过终止该子shell释放时,那么$?在父shell中将等于$的最终值?在终止的子shell中。
  • 一些内置函数可以修改$?取决于他们的结果。但有些人没有。
  • 内置函数“return”和“exit”,后面跟一个数值参数$?带参数,并终止执行。

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

# (exit 259)
# echo $?
3  

1
投票

首先,return是一个关键字,exit我的朋友是一个功能。

也就是说,这是最简单的解释。

return它从函数返回一个值。

exit退出或放弃当前的shell。

© www.soinside.com 2019 - 2024. All rights reserved.