在bash中对退出代码进行AND操作 [英] ANDing exit codes in bash
问题描述
我有一个bash脚本,对我的源代码进行三项检查,然后,如果所有命令都成功,则退出 exit 0
,如果其中任何命令失败,则退出 exit 1
:
I have a bash script that runs three checks over my source code, and then exit 0
if all the commands succeeded, or exit 1
if any of them failed:
#!/bin/bash
test1 ./src/ --test-1=option
exit_1=$?
test2 ./src/ test-2-options
exit_2=$?
test3 ./src/ -t 3 -o options
exit_3=$?
# Exit with error if any of the above failed
[[ $exit_1 -eq 0 && $exit_2 -eq 0 && $exit_3 -eq 0 ]]
exit $?
此代码有效,但是感觉太冗长和冗长.有什么办法可以使它变得更好吗?具体来说,我不满意:
This code works, but it feels overly long and verbose. Is there some way this can be made nicer? Specifically I am not happy with:
- 必须运行命令,然后然后将退出代码分配给变量
- 必须使用
[[... ...]]
,然后在下一行收集其退出代码以退出 - 必须像在
[[$ $ -eq 0]]
中那样将变量显式比较为0,而不是将它们视为布尔值.
- Having to run the command, and then assign the exit code to a variable
- Having to use
[[ ... ]]
, then collect its exit code on the next line to exit with - Having to explicitly compare variables to 0, as in
[[ $var -eq 0 ]]
, instead of treating them as booleans
理想情况下,最终结果将更具可读性,例如:
Ideally, the end result would be something more readable like:
exit_1=( test1 ./src/ --test-1=option )
exit_2=( test2 ./src/ test-2-options )
exit_3=( test3 ./src/ -t 3 -o options )
# Exit with error if any of the above failed
exit ( $exit_1 && $exit_2 && $exit_3 )
我考虑过的一些事情:
将错误代码放入一行中的变量中:
exit_1=$( test1 ./src/ --test-1=option )$?
exit_2=$( test2 ./src/ test-2-options )$?
exit_3=$( test3 ./src/ -t 3 -o options )$?
这有效,并且使它更短一些,但是我从未见过其他人使用过此功能.这是明智/理智的事情吗?这有什么问题吗?
This works, and makes this bit shorter, but I've never seen anyone else use this before. Is this a sensible/sane thing to do? Are there any issues with this?
只需运行测试,然后&&他们在一起:
test1 ./src/ --test-1=option && \
test2 ./src/ test-2-options && \
test3 ./src/ -t 3 -o options
status=$?
这不起作用,因为bash短路.如果 test1
失败,则test2和test3不运行,我希望它们全部运行.
This does not work, as bash short circuits. If test1
fails, test2 and test3 do not run, and I want them all to run.
检测错误并使用 ||退出退出
Detecing errors and exiting using || exit
[[ $exit_1 -eq 0 && $exit_2 -eq 0 && $exit_3 -eq 0 ]] || exit 1
这将保存一行尴尬的退出代码和变量,但是 exit 1
的重要位置现在位于该行的末尾,您可能会错过它.理想情况下,类似这样的方法会起作用:
This saves one line of awkward exit codes and variables, but the important bit of exit 1
is now right at the end of the line where you can miss it. Ideally, something like this would work:
exit [[ $exit_1 -eq 0 && $exit_2 -eq 0 && $exit_3 -eq 0 ]]
当然,这不是 的工作,因为 [[[
]返回其输出而不是回显它.
Of course, this does not work, as [[
returns its output instead of echoing it.
exit $( [[ $exit_1 -eq 0 && $exit_2 -eq 0 && $exit_3 -eq 0 ]] ; echo $? )
确实有效,但看起来仍然很可怕
does work, but still seems like a horrid cludge
未明确处理布尔值退出代码
[[ $exit_1 && $exit_2 && $exit_3 ]]
这并没有您希望的那样.&&&最简单的方法存储在变量中的三个返回码一起是完整的 $ var -eq 0&&...
.当然有更好的方法了吗?
This does not do what you would hope it would do. The easiest way of && together three return codes stored in variables is with the full $var -eq 0 && ...
. Surely there is a nicer way?
我知道bash并不是一种不错的编程语言-如果您甚至可以称呼它-但有什么办法可以使我不再那么尴尬?
I know bash is not a nice programming language - if you can even call it that - but is there any way I can make this less awkward?
推荐答案
您可以使用 bash
的算术命令对退出代码进行 OR
并取反,以获取退出代码1(如果其中任何一个代码非零).首先,一个例子:
You can use bash
's arithmetic command to OR
the exit codes together, and negate the result, to get an exit code of 1 if any of the codes is non-zero. First, an example:
$ ! (( 0 | 0 | 0 )); echo $?
0
$ ! (( 1 | 0 | 0 )); echo $?
1
现在,您的脚本:
#!/bin/bash
test1 ./src/ --test-1=option; exit_1=$?
test2 ./src/ test-2-options; exit_2=$?
test3 ./src/ -t 3 -o options; exit_3=$?
# Exit with error if any of the above failed. No need for a final
# call to exit, if this is the last command in the script
! (( $exit_1 || $exit_2 || $exit_3 ))
或者通常,您可以在运行任意数量的测试时累积退出代码:
Or in general, you can accumulate the exit codes as you run an arbitrary number of tests:
#!/bin/bash
# Unfortunately, ||= is not an assignment operator in bash.
# You could use |=, I suppose; you may not be able to assign
# any meaning to any particular non-zero value, though.
test1 ./src/ --test-1=option; (( exit_status = exit_status || $? ))
test2 ./src/ test-2-options; (( exit_status = exit_status || $? ))
test3 ./src/ -t 3 -o options; (( exit_status = exit_status || $? ))
# ...
testn ./src "${final_option_list[@]}"; (( exit_status = exit_status || $? ))
exit $exit_status # 0 if they all succeeded, 1 if any failed
这篇关于在bash中对退出代码进行AND操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!