[英]Exit a bash script from a function whose output is captured
我想在发生错误时完全终止/退出bash shell脚本,但使用的函数error
使我可以在终止前显示调试输出。 现在,我遇到的问题是,如果通过反引号或$()
捕获函数的输出,则错误函数内的exit 1
语句将不会终止shell脚本。
这是我的示例脚本:
#!/bin/bash
function error ()
{
echo "An error has occured: $1"
exit 1
}
function do_sth ()
{
if [ $1 -eq 0 ]; then
error "First param must be greater than 0!"
else
echo "OK!"
fi
}
RESULT=`do_sth 0`
echo "This line should never be printed"
如何立即在error()
函数中终止脚本?
命令替换的问题是,启动了一个子do_sth
来执行do_sth
。 然后, exit 1
终止此子shell,而不终止主bash。
您可以通过添加|| exit $?
解决此问题。 || exit $?
,它以命令替换中的退出代码退出
RESULT=`do_sth 0` || exit $?
如果要显示错误消息,请将其重定向到stderr
echo "An error has occured: $1" >&2
RESULT=`do_sth 0` || exit $?
然后回显“发生错误:$ 1”>&2
无法避免子shell无法使父对象直接终止的事实:父对象必须评估从子shell返回的值。 一种常见的技术是在退出功能中捕获退出并打印错误消息。 由于您是在子外壳程序中生成错误消息,因此不能像其他情况那样简单地将消息分配给变量,而是可以使用文件系统。 请注意,这种想法确实很愚蠢,仅将错误消息写入stderr会更清洁。 这就是它的用途,这就是为什么它被孩子们继承的原因。 就像是:
#!/bin/sh
trap final 0 2 15
# Create a temporary file to store error messages. This is a terrible
# idea: it would be much better to simply write error messages to stderr,
# but this code is attempting to demonstrate the technique of having the
# parent print the message. Perhaps it would do better to serve as an example
# of why reporting your children's mistakes is a bad idea. The children
# should be responsible for reporting their own errors. Doing so is easy,
# since they inherit file descriptor 2 from their parent.
errmsg=$( mktemp xxxxx )
final() {
test "$?" = 0 || cat $errmsg
rm -f $errmsg
} >&2
# Must emphasize one more time that this is a silly idea. The error
# function ought to be writing to stderr: eg echo "error: $*" >&2
error() { echo "error: $*" > $errmsg; exit 1; }
do_sth() {
if test "$1" -eq 0; then
error "First param must be greater than 0!"
else
echo "OK!"
fi
}
result=$( do_sth 0 ) || exit 1
echo not printed
似乎(聪明)答案是@FatalError在另一个问题的最高答案上,因此
这应该工作...
#!/bin/bash
trap "exit 1" 50 #exit process after receiving signal 50.
function myerror ()
{
echo "An error has occured: $1" >&2
}
function do_sth ()
{
if [ $1 -eq 0 ]; then
myerror "First param must be greater than 0!"
kill -50 $(ps --pid $$ -opid=) #uncommon signal 50 is used.
else
echo "OK!"
fi
}
RESULT=`do_sth 1`
echo $RESULT
RESULT=`do_sth 0`
echo $RESULT
echo "This line should never be printed"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.