在下面的情况下,该report
命令必须始终执行,但如果命令失败,我需要获得退出状态 1 test
:
test;report
echo $?
0
如何在不创建 shell 脚本的情况下在单个 bash 行中完成此操作?
答案1
保存并重复使用$?
。
test; ret=$?; report; exit $ret
如果您有多个测试命令并且想要运行所有命令,但要跟踪其中一个命令是否失败,则可以使用 bash 的 ERR 陷阱。
failures=0
trap 'failures=$((failures+1))' ERR
test1
test2
if ((failures == 0)); then
echo "Success"
else
echo "$failures failures"
exit 1
fi
答案2
除了包含 shell 命令的文件之外,什么是 shell 脚本?你可以假装它不是 shell 脚本和将其放在一行中,例如:
(test; r=$?; report; [ "$r" -gt 0 ] && exit 1; exit 0)
如果第一个命令返回;1
以外的任何内容,则退出子 shell。0
否则,它返回0
。
例如——我只是回显一些东西来代替运行一个真正的程序:
$ (false; r=$?; echo report; [ "$r" -gt 0 ] && exit 1; exit 0)
report
$ echo $?
1
$ (true; r=$?; echo report; [ "$r" -gt 0 ] && exit 1; exit 0)
report
$ echo $?
0
$ # example with an exit-status of 2:
$ (grep foo bar; r=$?; echo report; [ "$r" -gt 0 ] && exit 1; exit 0)
grep: bar: No such file or directory
report
$ echo $?
1
如果您定期设置errexit
shell 选项,则需要添加一个覆盖,以便子 shell 不会过早退出:
(set +o errexit; false; r=$?; echo report; [ "$r" -gt 0 ] && exit 1; exit 0)
答案3
你说“如果命令失败则退出状态1 test
”。假设您打算进行这种区分(即,即使test
命令以 2 或 3 等退出,您也希望退出值为 1 ),那么这是一个不错的解决方案:
test && { report; true; } || { report; false; }
如果您的意思并不是真正的“1”,但无论退出的非零值test
都可以作为您的整体退出代码,那么当前的最佳答案(保存并重用 $?)就可以正常工作。
答案4
这是一个非常糟糕的主意,但这似乎有效,可以带来一些灵感:
(trap report exit; test)