bash - 在 bash `if [ .. ]` 语句中检查命令是否成功

标签 bash if-statement

我正在尝试自动化我们的应用程序备份。该过程的一部分是在 if 语句中检查 egrep 的退出状态:

if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] ||
   [ egrep -i -q "error|warning|fatal|missing|critical" "$File" ]
then 
  echo "testing"
fi

我希望它输出 testing 因为文件存在并且 egrep 返回成功,但是我收到错误:

-bash: [: too many arguments

我尝试了各种语法 - 额外的括号、引号等,但错误仍然存​​在。

请帮助我理解我哪里出错了。

最佳答案

您犯了一个常见的错误,即假设 [if 语句语法的一部分。它不是; if 的语法很简单

if command; then
    : # ... things which should happen if command's result code was 0
else
    : # ... things which should happen otherwise
fi

我们使用的常见命令之一是[,它是命令test 的别名。这是一个用于比较字符串、数字和文件的简单命令。它接受相当狭窄的参数组合,如果您没有将预期的参数传递给它,它往往会生成令人困惑和误导的错误消息。 (或者更确切地说,一旦您习惯了错误消息就足够了并且很有帮助,但如果您不习惯它们,它们很容易被误解。)

在这里,您要检查命令 egrep 的结果:

if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] ||
   egrep -i -q "error|warning|fatal|missing|critical" "$File"
then
    echo "testing"
fi

一般情况下,command可以是一个管道或者一个命令列表;然后,最终命令的退出代码是 if 将检查的状态,类似于脚本中的最后一个命令如何决定脚本的退出状态。

这些复合命令可以任意复杂,比如

if read thing
    case $thing in
      '' | 'quit') false;;
      *) true;;
    esac
then ...

但在实践中,您很少会在 if 语句中看到不止一个命令(尽管这并非闻所未闻;您使用 || 的复合语句就是一个很好的例子!)

只是为了说明这一点,

if [ egrep foo bar ]

正在对参数 egrep foo bar 运行 [ aka test。但是没有选项的 [ 只接受一个参数,然后检查该参数是否为空字符串。 (egrep 显然不是一个空字符串。在这里引用是可选的,但可能更容易看到:

if [ "egrep" ]; then
    echo "yes, 'egrep' is not equal to ''"
fi

这显然是孤立的,但应该可以作为一个说明性的例子。)

test 作为一般厨房水槽的历史原因,作者不想成为 if 语法的一部分,是一种不太吸引人的设计原始的 Bourne shell。 Bash 和 zsh 提供了不那么笨拙的替代方案(比如 bash 中的 [[ 双括号),当然,POSIX test 很多比贝尔实验室的原创作品更温和。

关于bash - 在 bash `if [ .. ]` 语句中检查命令是否成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36371221/

相关文章:

c - 嵌套if和&&有什么区别?

MYSQL查询使用条件获取不同的值

ORACLE:需要导出表数据,列之间没有空格

linux - 在 Bash 中,有没有办法用双引号将变量展开两次?

linux - Bash 和 conda : Installing non-conda packages in conda environment with executable bash script

linux - 如何在sh中执行带有 "and"的if语句

bash - 在 native bash 中性能合理的十六进制解码?

bash - Cygwin 的 bash 在出错后变得非常慢

javascript - 使用三元 if...else 运算符时出错

javascript - 无法让此表单在 HTML5 上运行