我无法理解bash中return
内置的行为。这是一个示例脚本。
#!/bin/bash
dostuff() {
date | while true; do
echo returning 0
return 0
echo really-notreached
done
echo notreached
return 3
}
dostuff
echo returncode: $?
此脚本的输出为:
returning 0
notreached
returncode: 3
但是,如果从第4行删除date |
,则输出符合我的预期:
returning 0
returncode: 0
上面使用的return
语句似乎就像我认为break
语句应该表现的方式一样,但只有当循环位于管道的右侧时。为什么会这样?我无法在bash手册页或在线中找到任何解释此行为的内容。该脚本在bash 4.1.5和破折号0.5.5中的行为方式相同。
答案 0 :(得分:21)
在date | while ...
场景中,由于管道的存在,while循环在子shell中执行。因此,return语句打破了循环, subshell 结束,让你的函数继续运行。
您必须重新构建代码才能删除管道,以便不会创建子shell:
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
}
答案 1 :(得分:1)
但是return
应该终止函数调用,而不是子shell。 exit
旨在终止(子)shell。我想,这是一些无证的bug /功能。
echo|return
输入命令行会出错,这是正确的 - return
应该在函数中。
f(){ echo|return; }
在bash / dash中被接受,但return
不会终止函数调用。
如果return
终止子shell,它将在函数外部工作。因此,结论是: return
终止函数中的子shell ,这很奇怪。
答案 2 :(得分:1)
事情是:子shell是一个单独的过程 它实际上没有办法对父shell说:“我因为返回而退出”
在退出状态中没有这样的东西,这是父shell获得的唯一东西。
答案 3 :(得分:1)
如果函数内部return
,该函数将停止执行,但整个程序不会退出。
如果您在函数内部exit
,则整个程序将退出。
您不能在bash脚本的主体中return
,只能在函数或源脚本中return
。
例如:
#!/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'
运行上面的代码将输出:
a
c
d
答案 4 :(得分:0)
添加答案以解决bash的这一有趣功能。 。 。
返回if(或带有if / while / ...等表达式的任何控制命令)
如果使用简单和不太简单的表达式返回内部
subshell解释很好。控件返回到当前子外壳程序之外。这可能是bash函数。或者它可能是任何嵌套控制命令中带有导致子壳被调用的表达式。
用于非常简单的表达式,例如“ true”或“ 1 == 1”,不会调用任何子shell。因此return表现为〜normal / expected〜。
用于不太简单的表达式,例如扩展变量并与之比较,然后返回的行为就像中断;
简单(无子shell)示例:
$ 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
表达并不简单,并假定调用了subshell,返回行为就像break;
不简单(子外壳)示例。 。 = [[[]]内部:
$ rtest () { if [[ $DO =~ 1 ]] ; then echo one; return 2; echo two; fi; echo not simple; return 7; }
$ rtest
not simple
$ echo $?
7