mat*_*ots 17 shell bash exit-status
所以我有一个小脚本来运行一些测试。
javac *.java && java -ea Test
rm -f *.class
Run Code Online (Sandbox Code Playgroud)
现在的问题是,当我运行脚本时./test,即使测试因为rm -f *.class成功而失败,它也会返回成功退出代码。
我能想到的让它做我想做的事情的唯一方法对我来说很丑陋:
javac *.java && java -ea Test
test_exit_code=$?
rm -f *.class
if [ "$test_exit_code" != 0 ] ; then false; fi
Run Code Online (Sandbox Code Playgroud)
但这似乎是一个常见问题——执行任务,清理,然后返回原始任务的退出代码。
这样做的最惯用的方法是什么(在 bash 或一般的 shell 中)?
mur*_*uru 23
我会去:
javac *.java && java -ea Test
test_exit_code=$?
rm -f *.class
exit "$test_exit_code"
Run Code Online (Sandbox Code Playgroud)
为什么在exit可用时跳来跳去?
你可以使用一个trap:
trap 'last_error_code=$?' ERR
Run Code Online (Sandbox Code Playgroud)
例如:
$ trap 'last_error_code=$?' ERR
$ false
$ echo $?
1
$ echo $last_error_code $?
1 0
Run Code Online (Sandbox Code Playgroud)
Dav*_*d Z 11
据我所知,bash 最接近try...finally类似 C 的编程语言的块(如果它可用trap,这就是您可能想要的)是构造,其工作方式如下:
trap "rm -f *.class" EXIT
javac *.java && java -ea Test
Run Code Online (Sandbox Code Playgroud)
这将在您的脚本退出时执行“rm -f *.class”。如果你有更复杂的事情要做,你可以把它放在一个函数中:
cleanup() {
...
}
trap cleanup EXIT
javac *.java && java -ea Test
Run Code Online (Sandbox Code Playgroud)
如果你愿意,你可以把它变成一个相当通用的习语,它的工作原理大致类似于try...catch...finallyC 中的块。 像这样:
(
trap "catch_block; exit" ERR
trap finally_block EXIT
# contents of try goes here
)
Run Code Online (Sandbox Code Playgroud)
请注意,括号界定了一个子shell;使用这种结构,如果命令失败,则只有子外壳退出,而不是整个脚本。请记住,子外壳在计算上有些昂贵,因此不要使用太多(数百个)。根据您的脚本,您可以使用 shell 函数和 更有效地实现相同的效果trap ... RETURN,但这取决于您的调查。
您可以将exit和rm命令包装成一个简单的命令,eval例如:
java ... && java ...
eval "rm -f *.class; exit $?"
Run Code Online (Sandbox Code Playgroud)
$?传递给方式时的值exit是它在eval运行之前立即分配的任何值。
| 归档时间: |
|
| 查看次数: |
21976 次 |
| 最近记录: |