关于下面示例脚本的几个问题。
我正在调用一个函数_foo
并希望将其输出捕获到一个变量中$bar
,但也使用返回状态(可能不是0
or 1
),或者失败则停止exit
脚本(当非零时)。
- 为什么这样调用时
exit
in 函数不起作用?_foo
(if ! bar="$(_foo)"
)。当调用“正常”时它会起作用。exit
如果我将 if 语句更改为此(但我丢失了其输出),则会停止脚本:if ! _foo ; then
- 其
exit
行为类似于return
并且不会停止脚本:if ! bar="$(_foo)" ; then
- 仅调用一个没有赋值和退出的函数就可以了,但是像这样调用它却
var="$(func)"
不行。
_foo
是否有更好的方法来捕获函数中into的输出$bar
以及使用返回状态(对于0
or以外的其他情况1
,例如case
语句?)
我有一种感觉,我可能需要以trap
某种方式使用。
这是一个简单的例子:
#!/usr/bin/env bash
set -e
set -u
set -o pipefail
_foo() {
local _retval
echo "baz" && false
_retval=$?
exit ${_retval}
}
echo "start"
if ! bar="$(_foo)" ; then
echo "foo failed"
else
echo "foo passed"
fi
echo "${bar}"
echo "end"
这是输出:
$ ./foo.sh
start
foo failed
baz
end
这里还有一些例子:
这将退出:
#!/usr/bin/env bash
set -e
set -u
set -o pipefail
func() {
echo "func"
exit
}
var=''
func
echo "var is ${var}"
echo "did not exit"
这不会退出:
#!/usr/bin/env bash
set -e
set -u
set -o pipefail
func() {
echo "func"
exit
}
var=''
var="$(func)"
echo "var is ${var}"
echo "did not exit"
答案1
exit
在函数内退出整个脚本而不仅仅是函数(尽管有子 shell)。阐述:
#!/bin/bash
f() {
exit 3
}
f
exit 0
上面的脚本将以退出代码 3 终止,而
#!/bin/bash
f() {
exit 3
}
(f)
exit 0
将以退出代码 0 终止。
$(command)
您使用的语法在子 shell 内运行,command
并且exit
只能突破到子 shell 运行的层之内。
如果您想捕获在子 shell 中运行的某些内容的退出代码和输出,那么它仍然可用于启动子 shell 的环境:
#!/bin/bash
subshelloutput="$( echo "output"; exit 3 )"
returnval=$? # captures subshell's exit code
: more stuff follows
答案2
您也可以用另一种方式来做。
_foo ()
{
local _retval
declare -n output="$1" # $output is local (by default with declare in a func.)
## and points to $1
output="baz" && false
_retval=$?
echo ${_retval} # change echo to exit
}
现在_foo
这样调用:
$ _foo bar
1
$ echo "$bar"
baz
当您在函数定义中更改echo
为时,将退出脚本。exit
exit