Answers:
return
做一个明确的从一个shell函数或“点脚本”(一源脚本)的回报。如果return
未执行,则在shell函数或点脚本的末尾隐式返回。
如果return
执行时不带参数,则等同于返回最近执行的命令的退出状态。
这就是return
所有POSIX Shell中的工作方式。
例如,
gmx () {
echo 'foo'
return "$?"
}
因此等于
gmx () {
echo 'foo'
return
}
这与
gmx () {
echo 'foo'
}
通常,很少需要使用$?
。实际上,仅在需要保存它以备将来使用时才需要它,例如,如果您需要多次研究它的值(在这种情况下,您将其值分配给一个变量并对该变量执行一系列测试)。
sh
或posh
),return -- "$?"
如果有可能最后一条命令是返回负数的函数,则需要使用。mksh
(同样基于pdksh)禁止函数返回负值。
return x
功能与exit x
...的不同之处。我唯一了解的是return x
不会退出当前流程。
return
用于从函数或点脚本中返回。exit
做一些完全不同的事情(终止一个过程)。
从bash(1)
手册页:
执行时,功能的退出状态是主体中最后执行的命令的退出状态。
return
是一个内置命令-尽管return 1
与exit 1
等等有所不同
return
如果已指定,则将函数的退出状态强制为特定值。
return
并且exit
都是内置的,除了return
只能在函数中使用。您不能使用终止脚本return
。退出状态是命令返回的值。return
是返回该值的命令。因此,“返回语句只不过是退出状态”就不够准确。一个是值,另一个是命令加值。
return
从函数返回,exit
退出整个外壳。这是完全一样的,说下与return
对比exit(n)
,或者return
与sys.exit()
Python编写的。
我将在已经提供的答案中添加一些注意事项:
即使return
对shell有非常特殊的意义,从语法的角度来看,它也是shell内置命令,并且return语句像其他任何简单命令一样被解析。因此,这意味着像在任何其他命令的参数中一样,$?
如果不加引号,将受到split + glob的约束
因此,您需要引用它$?
来避免它:
return "$?"
return
通常不接受任何选项(ksh93
的接受通常的--help
,--man
,--author
...虽然)。它期望的唯一参数(可选)是返回码。接受的返回码范围因外壳而异,并且是否正确反映0..255以外的任何值$?
也因外壳而异。请参阅进程终止时的默认退出代码?有关详细信息。
大多数shell接受负数(毕竟,传递给_exit()
/ exitgroup()
system调用的参数是an int
,因此其值至少包含-2 31到2 31 -1,因此仅使shell接受相同范围的函数才有意义) 。
大多数shell使用waitpid()
和。用于检索退出状态的API,但是在这种情况下,当存储在中时,它会被截断为0到255之间的数字$?
。即使调用一个函数不涉及生成一个进程并用于waitpid()
检索其退出状态,因为所有操作都是在同一进程中完成的,但是许多shell也模仿了waitpid()
调用函数时的行为。这意味着即使您return
使用负值调用,$?
也将包含正数。
现在,在那些return
接受负数(ksh88,ksh93,bash,zsh,pdksh以及mksh,yash以外的派生数)的shell中,有一些(pdksh和yash)需要将其写成return -- -123
其他形式,-123
取为三个-1
,-2
,-3
无效的选项。
由于pdksh及其派生词(例如OpenBSD sh
或posh
)在中保留了负数$?
,这意味着return "$?"
当$?
包含负数时操作将失败(当最后一个运行命令是返回负数的函数时,将发生这种情况)。
因此return -- "$?"
在这些shell中会更好。但是请注意,尽管大多数外壳程序都支持该语法,但该语法不是POSIX,实际上不受mksh
ash派生工具支持。
因此,总而言之,对于基于pdksh的shell,您可以在函数的参数中使用负数,但如果这样做,return "$@"
将无法正常工作。在其他Shell中,return "$@"
它将起作用,并且您应避免使用负数(或0..255以外的数字)作为。的参数return
。
在我所知道的所有shell中,return
从在函数内部运行的子shell内部调用将导致该子shell退出(具有提供的退出状态(如果有的话,或最后一次运行命令的退出状态)),但不会导致该函数的返回(对我而言,尚不清楚POSIX是否为您提供保修,有人认为exit
应使用POSIX 代替功能内的出口子外壳。例如
f() {
(return 3)
echo "still inside f. Exit status: $?"
}
f
echo "f exit status: $?"
将输出:
still inside f. Exit status: 3
f exit status: 0
是的,函数的隐式返回值是最后执行的命令的退出状态。在任何shell脚本的任何时候都是如此。在脚本执行顺序中的任何时候,当前退出状态都是最后执行的命令的退出状态。偶数命令作为变量分配的一部分执行:var=$(exit 34)
。与函数的区别在于,函数可以在函数执行结束时更改退出状态。
更改“当前退出状态”的另一种方法是启动子shell并以任何所需的退出状态退出:
$ $(exit 34)
$ echo "$?"
34
是的,确实需要引用退出状态扩展:
$ IFS='123'
$ $(exit 34)
$ echo $?
4
一个(exit 34)
也工作。
有人可能会争辩说应该是更健壮的构造$(return 34)
,而退出应该“退出”正在执行的脚本。但$(return 34)
不适用于任何版本的bash。因此,它不是便携式的。
设置退出状态的最安全方法是使用它,因为它是为工作,定义和return
从功能而设计的:
exitstatus(){ return "${1:-"$?"}"; }
因此,在功能末尾。它是完全等同于有存在或是return
或return "$?"
。函数的结尾不必表示“函数的最后代码行”。
#!/bin/sh
exitstatus(){ a="${1:-"$?"}"; return "$a"; }
gmx(){
if [ "$1" = "one" ]; then
printf 'foo ';
exitstatus 78
return "$?"
elif [ "$1" = "two" ]; then
printf 'baz ';
exitstatus 89
return
else
printf 'baz ';
exitstatus 90
fi
}
将打印:
$ ./script
foo 78
baz 89
baz 90
唯一实际的用途"$?"
是打印其值:echo "$?"
或将其存储在变量中(因为它是一个临时值,并且在执行的每个命令中都会更改):(exitstatus=$?
请记住在类似的命令中引用该变量export EXITSTATUS="$?"
。
在该return
命令中,值的有效范围通常为0到255,但是请理解,126 + n
某些shell使用的值来表示特殊的退出状态,因此,一般建议使用0-125。
return
是对于像这样定义的函数f() (...; cmd; return)
,它阻止了一些外壳cmd
程序在与子外壳程序相同的过程中运行的优化。对于许多外壳程序,这也意味着该函数的退出状态不包含cmd
已被杀死的信息(大多数外壳程序无论如何都无法检索该信息)。