首页 > 解决方案 > 考虑特定的退出代码而不是失败并继续

问题描述

我发现了有关忽略shell 脚本中的 错误的问题,但它们忽略了任何错误,而不仅仅是一个特定的错误。

我的用例是在某些情况下my_command返回退出代码 -3 (253),但这不是真正的错误,任何&&-chained 命令都应该执行。如果退出代码不同!= 0,它应该停止。

所以基本上我正在寻找类似的东西

my_command || $(($?==253 ? true : false) && next_command

我已经查看了使用三元运算符的不同选项,但它们似乎都不适用于我的情况。

我能做些什么?

标签: bash

解决方案


有一些问题cmd1 || $(($?==253 ? true : false) && cmd2

  • 之后)缺少A。false
  • 你不想要$(( ... ))但是(( ... ))。前者会将表达式的结果(即数字!)作为命令执行后者只计算表达式,如果结果为 0 则失败,否则成功。请注意,这与退出代码的工作方式相反。
  • true这里false不是命令,而是变量。如果在内部使用了未定义的变量,则(( ... ))其值始终为 0。因此该命令((... ? true : false)) 始终失败

这是希望你可以写的:

cmd1 || (($?==253 ? 1 : 0)) && cmd2

测试:

prompt$ true || (($?==253 ? 1 : 0)) && echo ok
ok
prompt$ false  || (($?==253 ? 1 : 0)) && echo ok
prompt$ ( exit 253; )  || (($?==253 ? 1 : 0)) && echo ok
ok

但是,这里并不真正需要三元运算符。以下将是等效的:

cmd1 || (($?==253)) && cmd2

尽管如此,anif可能会更好。如果您不想使用一个内联,您可以为此编写一个函数:

# allow all exit codes given as the first argument
# multiple exit codes can be comma separated 
allow() {
   ok=",$1,"
   shift
   "$@"
   [[ "$ok" = *,$?,*  ]]
}
allow 0,253 cmd1 && cmd2

或者只为这个命令定义一个包装器

cmd1() {
    command cmd1 "$@" || (( $? == 253 ))
}
cmd1 && cmd2

推荐阅读