【问题标题】:Bash: conditional based on specific exit code of commandBash:基于命令的特定退出代码的条件
【发布时间】:2020-05-27 00:49:30
【问题描述】:

这个问题是Bash conditional based on exit code of command 的后续问题。

我了解并已使用该问题的公认答案:

$ cat ./txt
foo
bar
baz
$ if ! grep -Fx bax txt &>/dev/null; then echo "not found"; fi
not found
$

但我不知道用什么语法来实现一个看似简单的前提:如何为命令的特定退出代码编写条件?

This post 指出grep 可能会失败,错误代码 > 1;所以我想在grep返回错误代码1的情况下写上面的条件来打印“未找到”。我该如何写这样的语句?以下似乎不起作用(我显然在挣扎):

$ # Sanity-check that grep really fails with error code 1:
$ grep -Fx bax txt &>/dev/null
$ echo $?
1
$
$
$ if grep -Fx bax txt &>/dev/null -eq 1; then echo "not found"; fi
$ if grep -Fx bax txt &>/dev/null == 1; then echo "not found"; fi
$ if grep -Fx bax txt &>/dev/null = 1; then echo "not found"; fi
$ if [ grep -Fx bax txt &>/dev/null -eq 1 ]; then echo "not found"; fi
$ if [ grep -Fx bax txt &>/dev/null == 1 ]; then echo "not found"; fi
$ if [ grep -Fx bax txt &>/dev/null = 1 ]; then echo "not found"; fi
$

注意:我特别想避免先运行命令,然后在条件中使用$?,原因已在第一个注明的帖子的接受答案中指出。

【问题讨论】:

  • grep -Fqx bax txt; (($? == 1)) && echo not found
  • 虽然您发布的代码没有任何问题,但如果$? 的值不为零,则它会执行回显,这意味着错误,因为如果出现以下情况,则不需要测试$? 的值您只对 1 作为值感兴趣。

标签: bash conditional-statements


【解决方案1】:

如果您想对不同的错误代码做出不同的响应(而不仅仅是成功/失败,如链接问题中所示),您需要运行该命令,然后检查 $? 以获取其特定的退出状态:

grep -Fx bax txt &>/dev/null
if [ $? -eq 1 ]; then
    echo "not found"
fi

(在我对链接问题的回答中,我将测试 $? 是否为零描述为货物崇拜编程;这不适用于检查特定的非零值。)

请注意,$? 会为每个运行的命令重新设置 - 包括从上一个命令测试 $? 的命令 - 所以如果你想用它做不止一件事,你必须立即 将其存储在变量中,然后在该变量上运行测试:

curl "$url"
curl_status=$?
if [ "$curl_status" -eq 6 ]; then
    echo "Couldn't resolve host name"
elif [ "$curl_status" -eq 7 ]; then
    echo "Couldn't connect to host"
elif [ "$curl_status" -ne 0 ]; then
    echo "Some sort of error occurred; curl status was $curl_status"
fi

请注意,使用! 来否定命令的成功/失败会有效地破坏特定的错误代码,因为它将所有非零代码转换为相同的结果:零。如果你想做 if ! command ... 的等效操作并且仍然可以访问特定代码,我最喜欢的习惯用法是使用 || 和大括号组,如下所示:

curl "$url" || {
    curl_status=$?
    ...
    # Do error handling/reporting based on $curl_status
    ...
}

【讨论】:

  • 整洁:回答者对我原始参考的回答! :) 为什么在这种情况下,确实需要求助于 $? 而如果只测试零/非零,您可以在单线中进行,而无需 $? ?我对 C/C++ 最有经验,我想我期待某种形式的模拟右值/临时变量的概念——这个概念在这里不适用吗?
  • @StoneThrow 这是因为if(以及whileuntil 和...)固有地测试零/非零,因此编写显式零测试是多余的;但它们测试特定的非零状态,因此对于这些测试,您必须编写显式测试。
猜你喜欢
  • 2018-09-25
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 2013-08-26
  • 2018-11-04
相关资源
最近更新 更多