Answers:
从man bash
开始return [n]
;
使函数停止执行,并将n指定的值返回给其调用方。如果省略n,则返回状态为函数体内执行的最后一条命令的返回状态。
...在exit [n]
:
使外壳退出,状态为n。如果省略n,则退出状态为最后执行的命令的退出状态。在外壳终止之前执行EXIT上的陷阱。
编辑:
根据您对问题的编辑,关于退出代码,return
与退出代码无关。退出代码仅适用于应用程序/脚本,而不适用于功能。因此,就此而言,设置脚本退出代码的唯一关键字(调用程序可以使用$?
shell变量捕获的退出代码)为exit
。
编辑2:
我最近提到的声明exit
引起了一些评论。这样做是为了区分return
和exit
理解OP,实际上,在程序/ shell脚本的任何给定点,这exit
都是用退出代码结束调用过程结束脚本的唯一方法。
在shell中执行的每个命令都会生成一个本地的“退出代码”:它将$?
变量设置为该代码,并且可以与和其他运算符一起使用if
, &&
以有条件地执行其他命令。
这些退出代码(以及$?
变量的值)在每次执行命令时都会重置。
顺便提一句,由脚本执行的最后一个命令的退出代码被用作调用过程所看到的脚本本身的退出代码。
最后,函数在被调用时就作为针对退出代码的shell命令。使用来设置功能(在功能内)的退出代码return
。因此,当在函数return 0
中运行时,函数执行终止,给出退出代码0。
func(){ return 50; };func;echo $?
50。因此$?
shell变量似乎并不限于exit
。
$?
扩展到最近执行的前台管道的退出状态。” 该退出可能是通过调用exit
(或击中脚本的结尾)的形式或以调用return
函数内部的形式从外壳中退出的。
$?
当前进程/脚本exit
的结果仅限于此脚本执行的最后一条命令或结果。因此,如果最后一个脚本行是对该函数的调用,并且该函数返回50,是的$?
,您对调用您的进程产生的那个是50。但是,这与无关return
,因为这是限于当前脚本。仅当此函数调用是脚本的最后一句话时才返回它。exit
但是,始终完成脚本并返回$?
有关调用过程的值。
return
与退出代码无关”这一行感到困惑。实验告诉我,函数的返回代码和脚本的退出代码之间没有功能上的区别。
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()
$?
。
echo fnord | while read x; do exitfunc; done; echo "still here"
将打印“仍在此处”。while
在这种情况下,似乎只有子外壳退出了。
done || exit $?
但这很丑陋,并且并非完全等效。
return
将导致当前函数或源脚本超出范围`'' 。
我认为没有人真正完全回答过这个问题,因为他们没有描述两者的用法。好的,我想我们知道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"
在此示例中,测试可用于指示是否找到目录。请注意,返回后的任何内容都不会在函数中执行。在外壳程序中,0是true,但false是1,与其他prog langs不同。
有关函数的更多信息:http : //www.linuxjournal.com/content/return-values-bash-functions
注意:isdirectory函数仅用于指导目的。这不应该是您在真实脚本中执行此类选项的方式。
test -d $1
以达到相同的结果。永远不要做if <check> return else return
。<check>
至少在我所知道的所有语言中,单单都会做同样的事情。
isdirectory() { [ -d "$1" ]; }
行为与您在此处的行为完全相同:shell函数的默认返回值,无论是到达其代码的结尾还是return
不带任何参数的a,都是最新命令。
return
声明的行为。的确,他的例子很简单,不用于生产。但这很简单,因此可以很好地完成他的任务。没错。
请记住,函数是脚本内部的函数,通常使用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种不同的失败原因。
您可以设置调用脚本中包含的变量,或在函数中回显结果,并在调用脚本中使用命令替换。但是返回和退出的目的是传递状态代码,而不是像C这样的编程语言所期望的传递值或计算结果。
有时,您使用.
或运行脚本source
。
. a.sh
如果您exit
在中添加a.sh
,它不仅会终止脚本,还会终止您的Shell会话。
如果您return
在中添加a.sh
,它只会停止处理脚本。
return: can only 'return' from a function or sourced script
,这使其不适合一般脚本。
all
情况都不适合。在当前外壳中使用.
或source
运行脚本,而不是生成子外壳。该脚本必须知道如何使用。对相反的用户不利。就个人而言,我建议在第一次运行脚本之前先阅读它们。
trap
函数ERR EXIT
,然后先保存失败命令的退出代码,errCode=$?
然后退出脚本(无论是否提供),return $errCode || exit $errCode
其中的||
意思是“如果我因为不提供而无法返回, ,请退出。”
exit
终止当前进程 ; 有或没有退出代码,都应将其视为系统而不是程序功能。请注意,在寻找资源时,exit
将结束外壳程序,但是在运行时将仅exit
脚本。
return
从函数返回到调用后的指令(带或不带返回码)。return
是可选的,在函数末尾隐式包含。return
只能在函数内部使用。
我想补充一点,在获取源代码的同时,要想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
-并且-外壳将关闭。
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
都将退出。
(
和)
放置该块,从而有效地撤消.
(source)命令,就好像您已正常运行测试脚本一样,该命令位于子壳中。该脚本未与IOf一起运行,.
或者source
实际上没有2个子Shell。
OP的问题:就退出代码而言,BASH函数中的return和exit语句有什么区别?
首先,需要进行一些澄清:
在上面的项目符号列表中,始终从第一项或从第二项中选择“(x | y)”,以分别获取有关函数&return或shells&exit的语句。
清楚的是,它们都共享特殊变量$的通用用法吗?在值终止后向上传递值。
*现在以特殊方式表示$?可以设置:
值得注意的是$?可以通过在子外壳中调用exit来分配值,如下所示:
# (exit 259)
# echo $?
3
exit 259
回显为,3
因为最终退出值是一个字节。 259 % 256 = 3
首先return
是一个关键字exit
我的朋友是一个函数。
也就是说,这是最简单的解释。
return
它从函数返回一个值。
exit
它退出当前的shell或放弃当前的shell。
return
而是关键字。返回不仅限于退出代码,这就是为什么比较不公平的原因。
exit
也不return
是bash手册所说的“保留字”。从bash函数的意义上讲,任何一个都不是“函数”。两者都是内置命令,使用bash术语。(这里是被称为C标准库函数exit()
,以及C编程语言有一个保留字return
,但这些不应该与在bash命令混淆,即使它们的语义是好奇相似。)
help <command>
在您的shell中键入以获取有关shell内置功能的信息。你的情况help return
和help exit