考虑以下代码
外部作用域.sh
#!/bin/bash
set -e
source inner-scope.sh
echo $(inner)
echo "I thought I would've died :("
Run Code Online (Sandbox Code Playgroud)
内部作用域.sh
#!/bin/bash
function inner() { echo "winner"; return 1; }
Run Code Online (Sandbox Code Playgroud)
我试图outer-scope.sh在调用inner()失败时退出。由于$()调用子外壳,这不会发生。
如何在保留函数可能以非零退出代码退出的事实的同时获得函数的输出?
use*_*686 135
$()保留退出状态;您只需要在没有自身状态的语句中使用它,例如赋值。
输出=$(内部)
在此之后,$?将包含 的退出状态inner,您可以对其进行各种检查:
output=$(inner) || exit $?
echo $output
Run Code Online (Sandbox Code Playgroud)
或者:
if ! output=$(inner); then
exit $?
fi
echo $output
Run Code Online (Sandbox Code Playgroud)
或者:
if output=$(inner); then
echo $output
else
exit $?
fi
Run Code Online (Sandbox Code Playgroud)
(注意:exit不带参数的bare等价于exit $?——也就是说,它以最后一个命令的退出状态退出。我使用第二种形式只是为了清楚起见。)
另外,为了记录:source在这种情况下完全无关。您可以只inner()在outer-scope.sh文件中定义,结果相同。
rye*_*nus 42
如果您同时想要(输出和退出状态):
output=$(command)
status=$?
Run Code Online (Sandbox Code Playgroud)
注意函数局部变量的棘手情况,比较以下代码:
f() { local v=$(echo data; false); echo output:$v, status:$?; }
g() { local v; v=$(echo data; false); echo output:$v, status:$?; }
Run Code Online (Sandbox Code Playgroud)
我们会得到:
$ f # fooled by 'local' with inline initialization
output:data, status:0
$ g # a good one
output:data, status:1
Run Code Online (Sandbox Code Playgroud)
当子shell的输出用于初始化local变量时,退出状态不再是子shell的,而是命令的,最有可能是.local 0
#!/bin/bash
set -e
source inner-scope.sh
foo=$(inner)
echo $foo
echo "I thought I would've died :("
Run Code Online (Sandbox Code Playgroud)
通过添加echo,子 shell 不会独立运行(不会单独检查)并且不会中止。赋值可以避免这个问题。
您也可以执行此操作,并将输出重定向到文件,以便稍后处理它。
tmpfile=$( mktemp )
inner > $tmpfile
cat $tmpfile
rm $tmpfile
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
73862 次 |
| 最近记录: |