bash 函数中 return 语句的行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7109720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Behavior of return statement in bash functions
提问by A B
I'm having trouble understanding the behavior of the returnbuilt-in in bash. Here is a sample script.
我无法理解return内置 bash的行为。这是一个示例脚本。
#!/bin/bash
dostuff() {
date | while true; do
echo returning 0
return 0
echo really-notreached
done
echo notreached
return 3
}
dostuff
echo returncode: $?
The output of this script is:
这个脚本的输出是:
returning 0
notreached
returncode: 3
If, however, the date |is removed from line 4, the output is as I expected:
但是,如果date |从第 4 行中删除了 ,则输出与我预期的一样:
returning 0
returncode: 0
It seems like the returnstatement as used above is acting the way I thought the breakstatement ought to behave, but only when the loop is on the right hand side of a pipe. Why is this the case? I couldn't find anything to explain this behavior in the bash man page or online. The script acts the same way in bash 4.1.5 and dash 0.5.5.
return上面使用的语句似乎按照我认为break语句应该表现的方式行事,但仅当循环位于管道的右侧时。为什么会这样?我在 bash 手册页或在线找不到任何可以解释这种行为的内容。该脚本在 bash 4.1.5 和 dash 0.5.5 中的作用相同。
回答by glenn Hymanman
In the date | while ...scenario, that while loop is executed in a subshell due to the presence of the pipe. Thus, the return statement breaks the loop and the subshellends, leaving your function to carry on.
在这个date | while ...场景中,由于管道的存在,while 循环在子外壳中执行。因此,return 语句中断循环,子shell结束,让您的函数继续执行。
You'll have to reconstruct the code to remove the pipeline so that no subshells are created:
您必须重建代码以删除管道,以便不创建子外壳:
dostuff() {
# redirect from a process substitution instead of a pipeline
while true; do
echo returning 0
return 0
echo really-notreached
done < <(date)
echo notreached
return 3
}
回答by Derek Soike
If you returninside a function, that function will stop executing but the overall program will not exit.
如果您return在函数内部,该函数将停止执行但整个程序不会退出。
If you exitinside a function, the overall program will exit.
如果你exit在一个函数里面,整个程序就会退出。
You cannot returnin the main body of a bash script, you can only returninside a function or sourced script.
您不能return在 bash 脚本的主体中,只能return在函数或源脚本中。
For example:
例如:
#!/usr/bin/env bash
function doSomething {
echo "a"
return
echo "b" # this will not execute because it is after 'return'
}
function doSomethingElse {
echo "d"
exit 0
echo "e" # this will not execute because the program has exited
}
doSomething
echo "c"
doSomethingElse
echo "f" # this will not execute because the program exited in 'doSomethingElse'
Running the above code will output:
运行上面的代码会输出:
a
c
d
回答by motas
But returnshould terminate a function call, not a subshell. exitis intended to terminate (sub)shell. I think, it's some undocumented bug/feature.
但return应该终止函数调用,而不是子shell。exit旨在终止(子)shell。我认为,这是一些未记录的错误/功能。
echo|returntyped in commandline gives an error, that's correct - returnshould be in a function.
echo|return在命令行中输入会出现错误,这是正确的 -return应该在函数中。
f(){ echo|return; }is accepted in the bash/dash, but returndoesn't terminate a function call.If returnterminates a subshell, it would work outside a function. So, conclusion is: returnterminates a subshell in a functionwhich is strange.
f(){ echo|return; }在 bash/dash 中被接受,但return不会终止函数调用。如果return终止子shell,它将在函数之外工作。所以,结论是:return在一个奇怪的函数中终止一个子shell。
回答by pgas
The thing is: the subshell is a separate process It doesn't really have a way to say to the parent shell: "I'm exiting because of a return"
问题是:子shell是一个单独的进程它真的没有办法对父shell说:“我因为返回而退出”
There is no such thing in the exit status which is the only thing the parent shell gets.
退出状态中没有这样的东西,这是父 shell 唯一得到的东西。
回答by gaoithe
Adding an answer to cover this interesting feature of bash . . .
添加答案以涵盖 bash 的这一有趣功能。. .
return inside if (or any control command with expression like if/while/...)
return inside if with simple and less simple expressions
在 if 内部返回(或任何带有 if/while/... 等表达式的控制命令)
用简单和不那么简单的表达式返回内部 if
The subshell explanation is good. Control returns out of the current subshell. Which might be the bash function. Or it might be any of the nested control commands with an expression which has caused a subshell to be invoked.
子shell的解释很好。控制从当前子外壳返回。这可能是 bash 函数。或者它可能是任何嵌套的控制命令,它带有一个导致调用子外壳的表达式。
for very simple expressions e.g. "true" or "1 == 1" there is no subshell invoked. So return behaves as ~normal/expected~.
for less simple expressions e.g. variable expanded and compared with something then return behaves like break;
对于非常简单的表达式,例如“true”或“1 == 1”,没有调用子shell。所以 return 表现为 ~normal/expected~。
对于不那么简单的表达式,例如变量扩展并与某些内容进行比较,然后 return 的行为类似于 break;
SIMPLE (no subshell) examples:
简单(无子外壳)示例:
$ rtest () { if true; then echo one; return 2; echo two; fi; echo not simple; return 7; }
$ rtest
one
$ echo $?
2
$ rtest () { if [[ 1 == 1 ]] ; then echo one; return 2; echo two; fi; echo not simple; return 7; }
$ rtest
one
$ echo $?
2
$ rtest () { if [[ 1 =~ 1 ]] ; then echo one; return 2; echo two; fi; echo not simple; return 7; }
$ rtest
one
$ echo $?
2
$ rtest () { if $DO ; then echo one; return 2; echo two; else echo three; return 3; fi; echo not simple; return 7; }
$ rtest
one
$ echo $?
2
$ rtest () { if [[ $DO ]]; then echo one; return 2; echo two; else echo three; return 3; fi; echo not simple; return 7; }
$ rtest
three
$ echo $?
3
$ rtest () { if [[ $DO == 1 ]] ; then echo one; return 2; echo two; else echo three; return 3; echo four; fi; echo not simple; return 7; }
$ rtest; echo $?
one
2
$ DO=1; rtest; echo $?
one
2
$ DO=0; rtest; echo $?
three
3
Expression not simple and presuming subshell is invoked, return behaviour is like break;
表达式不简单,假设子shell被调用,返回行为如break;
NOT SIMPLE (subshell) example . . =~ inside [[ ]] :
不简单(子外壳)示例。. =~ 在 [[ ]] 中:
$ rtest () { if [[ $DO =~ 1 ]] ; then echo one; return 2; echo two; fi; echo not simple; return 7; }
$ rtest
not simple
$ echo $?
7

