Bash 函数中 return 和 exit 的区别

发布于 2024-10-07 08:28:35 字数 72 浏览 1 评论 0原文

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

What is the difference between the return and exit statement in Bash functions with respect to exit codes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

鸠魁 2024-10-14 08:28:36
  • exit 终止当前进程;无论有或没有退出代码,都应将其视为系统而不是程序功能。请注意,当采购时,exit将结束壳。但是,运行时,它只会退出脚本。

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

我想补充一点,在获取源代码时,要在不终止 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 -并且 - 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 会退出。

  • exit terminates the current process; with or without an exit code, consider this a system more than a program function. Note that when sourcing, exit will end the shell. However, when running, it will just exit the script.

  • return from a function go back to the instruction after the call, with or without a return code. return is optional and it's implicit at the end of the function. return can only be used inside a function.

I want to add that while being sourced, it's not easy to exit the script from within a function without killing the shell. I think, an example is better on a 'test' script:

#!/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"

doing the following:

user$ ./test
Whatever is not available
user$

test -and- the shell will close.

user$ . ./test
Whatever is not available

Only test will finish and the prompt will show.

The solution is to enclose the potentially procedure in ( and ):

#!/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

Now, in both cases only test will exit.

桜花祭 2024-10-14 08:28:36

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

首先,需要澄清一些:

  • 不需要 (return|exit) 语句来终止 (function|shell) 的执行。当 (function|shell) 到达其代码列表末尾时,即使没有 (return|exit) 语句,它也会终止。

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

    $ 的价值?在(称为函数 | 子 shell)中执行的最后一个命令之后是传递回(函数调用者 | 父 shell)的值。无论执行的最后一个命令是(“return [n]”|“exit [n]”)还是普通命令(“return”或恰好是被调用函数代码中的最后一个命令的其他命令,情况都是如此。

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

很明显,它们都共享特殊变量的共同用法。 $? 在终止后向上传递值

* 现在介绍可以设置 $? 的特殊方法:

  • 当被调用函数终止并返回到其调用者时,$?调用者中的值将等于终止函数中 $? 的最终值。
  • 当父 shell 隐式或显式等待单个子 shell 并通过该子 shell 的终止而释放时,<父 shell 中的 code>$? 将等于终止的子 shell 中的 $? 的最终值。
  • 某些内置函数可以修改 $?。 > 取决于他们的结果。但有些人则不然。
  • 内置函数“return”和“exit”,当后跟数字参数时,都会设置 $? 及其参数,并终止执行。

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

# (exit 259)
# echo $?
3

The OP's question:
What is the difference between the return and exit statement in BASH functions with respect to exit codes?

Firstly, some clarification is required:

  • A (return|exit) statement is not required to terminate execution of a (function|shell). A (function|shell) will terminate when it reaches the end of its code list, even with no (return|exit) statement.

  • A (return|exit) statement is not required to pass a value back from a terminated (function|shell). Every process has a built-in variable $? which always has a numeric value. It is a special variable that cannot be set like "?=1", but it is set only in special ways (see below *).

    The value of $? after the last command to be executed in the (called function | sub shell) is the value that is passed back to the (function caller | parent shell). That is true whether the last command executed is ("return [n]"| "exit [n]") or plain ("return" or something else which happens to be the last command in the called function's code.

In the above bullet list, choose from "(x|y)" either always the first item or always the second item to get statements about functions and return, or shells and exit, respectively.

What is clear is that they both share common usage of the special variable $? to pass values upwards after they terminate.

* Now for the special ways that $? can be set:

  • When a called function terminates and returns to its caller then $? in the caller will be equal to the final value of $? in the terminated function.
  • When a parent shell implicitly or explicitly waits on a single sub shell and is released by termination of that sub shell, then $? in the parent shell will be equal to the final value of $? in the terminated sub shell.
  • Some built-in functions can modify $? depending upon their result. But some don't.
  • Built-in functions "return" and "exit", when followed by a numerical argument both set $? with their argument, and terminate execution.

It is worth noting that $? can be assigned a value by calling exit in a sub shell, like this:

# (exit 259)
# echo $?
3
伪心 2024-10-14 08:28:36

简而言之(主要针对编码新手),我们可以说,

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

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

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

In simple words (mainly for newbie in coding), we can say,

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

Also if you observed, this is very basic, but...,

    `return`: is the keyword
    `exit()`: is the function
§对你不离不弃 2024-10-14 08:28:36

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

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

If you convert a Bash script into a function, you typically replace exit N with return N. The code that calls the function will treat the return value the same as it would an exit code from a subprocess.

Using exit inside the function will force the entire script to end.

也只是曾经 2024-10-14 08:28:36

为其他一些答案添加可操作的方面:

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

Return 通常用于在当前 shell 中运行的交互式脚本,通过 调用。例如,script.sh,并且只会将您返回到调用 shell。然后调用 shell 就可以访问返回代码 - $? 为您提供定义的返回状态。
在这种情况下,退出还会关闭您的 shell(包括 SSH 连接,如果您是这样工作的话)。

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

Adding an actionable aspect to a few of the other answers:

Both can give exit codes - default or defined by the function, and the only 'default' is zero for success for both exit and return. Any status can have a custom number 0-255, including for success.

Return is used often for interactive scripts that run in the current shell, called with . script.sh for example, and just returns you to your calling shell. The return code is then accessible to the calling shell - $? gives you the defined return status.
Exit in this case also closes your shell (including SSH connections, if that's how you're working).

Exit is necessary if the script is executable and called from another script or shell and runs in a subshell. The exit codes then are accessible to the calling shell - return would give an error in this case.

梦里梦着梦中梦 2024-10-14 08:28:36

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

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

return

它从函数返回一个值。

exit

它退出或放弃当前 shell。

First of all, return is a keyword and exit is a function.

That said, here's a simplest of explanations.

return

It returns a value from a function.

exit

It exits out of or abandons the current shell.

爱*していゐ 2024-10-14 08:28:35

来自 return [n] 上的 man bash

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

...退出 [n] 时:

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

编辑:

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

编辑2:

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

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

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

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

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

From man bash on return [n];

Causes a function to stop executing and return the value specified by n to its caller. If n is omitted, the return status is that of the last command executed in the function body.

... on exit [n]:

Cause the shell to exit with a status of n. If n is omitted, the exit status is that of the last command executed. A trap on EXIT is executed before the shell terminates.

EDIT:

As per your edit of the question, regarding exit codes, return has nothing to do with exit codes. Exit codes are intended for applications/scripts, not functions. So in this regard, the only keyword that sets the exit code of the script (the one that can be caught by the calling program using the $? shell variable) is exit.

EDIT 2:

My last statement referring exit is causing some comments. It was made to differentiate return and exit for the understanding of the OP, and in fact, at any given point of a program/shell script, exit is the only way of ending the script with an exit code to the calling process.

Every command executed in the shell produces a local "exit code": it sets the $? variable to that code, and can be used with if, && and other operators to conditionally execute other commands.

These exit codes (and the value of the $? variable) are reset by each command execution.

Incidentally, the exit code of the last command executed by the script is used as the exit code of the script itself as seen by the calling process.

Finally, functions, when called, act as shell commands with respect to exit codes. The exit code of the function (within the function) is set by using return. So when in a function return 0 is run, the function execution terminates, giving an exit code of 0.

何以心动 2024-10-14 08:28:35

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 will cause the current function to go out of scope, while exit will cause the script to end at the point where it is called. Here is a sample program to help explain this:

#!/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()
鲜肉鲜肉永远不皱 2024-10-14 08:28:35

我认为没有人真正完全回答了这个问题,因为他们没有描述两者的使用方式。好的,我想我们知道 exit 会杀死脚本,无论它在哪里调用,您也可以为其分配一个状态,例如 exit 或 exit 0 或 exit 7 等等。这可用于确定脚本在被另一个脚本调用时如何强制停止,等等。退出就足够了。

return,当被调用时,将返回指定的值来指示函数的行为,通常是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"

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

有关函数的更多信息:从 Bash 函数返回值< /em>

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

I don't think anyone has really fully answered the question because they don't describe how the two are used. OK, I think we know that exit kills the script, wherever it is called and you can assign a status to it as well such as exit or exit 0 or exit 7 and so forth. This can be used to determine how the script was forced to stop if called by another script, etc. Enough on exit.

return, when called, will return the value specified to indicate the function's behavior, usually a 1 or a 0. For example:

    #!/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"
    }

Check like this:

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

Or like this:

    isdirectory || echo "not a directory"

In this example, the test can be used to indicate if the directory was found. Notice that anything after the return will not be executed in the function. 0 is true, but false is 1 in the shell, different from other programming languages.

For more information on functions: Returning Values from Bash Functions

Note: The isdirectory function is for instructional purposes only. This should not be how you perform such an option in a real script.*

独享拥抱 2024-10-14 08:28:35

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

“Bash 函数中的 return 和 exit 语句之间关于退出代码的差异”非常小。两者都返回状态,而不是值本身。状态为零表示成功,而任何其他状态(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 语句的情况下结束,则最后执行的命令的状态将作为状态代码返回(并将放置在 $? 中)。

请记住,返回和退出会返回 0 到 255 之间的状态代码,可在 $? 中找到。您不能将任何其他内容填充到状态代码中(例如,返回“cat”);这是行不通的。但是,脚本可以通过使用状态代码传回 255 个不同的失败原因。

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

Remember, functions are internal to a script and normally return from whence they were called by using the return statement. Calling an external script is another matter entirely, and scripts usually terminate with an exit statement.

The difference "between the return and exit statement in Bash functions with respect to exit codes" is very small. Both return a status, not values per se. A status of zero indicates success, while any other status (1 to 255) indicates a failure. The return statement will return to the script from where it was called, while the exit statement will end the entire script from wherever it is encountered.

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

If your function simply ends without a return statement, the status of the last command executed is returned as the status code (and will be placed in $?).

Remember, return and exit give back a status code from 0 to 255, available in $?. You cannot stuff anything else into a status code (e.g., return "cat"); it will not work. But, a script can pass back 255 different reasons for failure by using status codes.

You can set variables contained in the calling script, or echo results in the function and use command substitution in the calling script; but the purpose of return and exit are to pass status codes, not values or computation results as one might expect in a programming language like C.

少女的英雄梦 2024-10-14 08:28:35

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

. a.sh

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

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

Sometimes, you run a script using . or source.

. a.sh

If you include an exit in the a.sh, it will not just terminate the script, but end your shell session.

If you include a return in the a.sh, it simply stops processing the script.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文