在大多数情况下,我希望我的脚本在遇到意外错误时终止,因此通常以set -e -u -E -o pipefail
开始。
但是,有时我需要捕获单个调用的退出代码,然后 not 终止。这样会导致类似
的构造# (1) Verbose. Breaks when moved between scripts
# with different global -e setting.
set +e
COMMAND WITH A LOT OF ARGUMENTS \
| AND MAYBE EVEN PIPES \
| MAYBE OVER MANY LINES
exitCode=$?
set -e
# (2) Verbose.
if COMMAND WITH A LOT OF ARGUMENTS \
| AND MAYBE EVEN PIPES \
| MAYBE OVER MANY LINES
then exitCode=$?
else exitCode=$?
fi
# (3)
exitCode=0
COMMAND WITH A LOT OF ARGUMENTS \
| AND MAYBE EVEN PIPES \
| MAYBE OVER MANY LINES \
|| exitCode=$?
# (4) Brittle, must not mix up order of && and ||
COMMAND WITH A LOT OF ARGUMENTS \
| AND MAYBE EVEN PIPES \
| MAYBE OVER MANY LINES \
&& exitCode=$? || exitCode=$?
# (5), doesn't work with `set -o pipefail`
COMMAND WITH A LOT OF ARGUMENTS \
| AND MAYBE EVEN PIPES \
| MAYBE OVER MANY LINES | cat
exitCode=$PIPESTATUS
# (6) Requires maintaining a function across scripts.
captureExitCode COMMAND WITH A LOT OF ARGUMENTS \
| AND MAYBE EVEN PIPES \
| MAYBE OVER MANY LINES
# where
captureExitCode() {
# any of the above constructs with "$@" as command
}
所有这些都是冗长的,或者在视觉上很难解析,尤其是在COMMAND ...
是多行管道命令的情况下。至少,他们没有很好地传达自己的意图。对于captureExitCode
,该功能必须跨脚本重现。
是否有一些不太详细的内置习惯来捕获退出代码?
答案 0 :(得分:0)
在子外壳中运行有问题的命令并禁用errexit
:
(
set +e
run buggy code failing without proper error handling
)
exitcode=$?
示例:
#! /bin/bash
set -e
if ( set +e
false
)
then
echo success
else
echo failure
fi
顺便说一句:以这种方式编写管道时,不需要反引号:
echo abc |
tr a x |
sed 's/^x/y/'