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

Abh*_*hal 3 bash if-statement

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

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

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

-bash: [: too many arguments
Run Code Online (Sandbox Code Playgroud)

我尝试了各种语法 - 附加括号,引号等但错误仍然存​​在.

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

tri*_*eee 7

你犯了一个常见错误,认为这[if语句语法的一部分.它不是; if简单的语法

if command; then
    : # ... things which should happen if command's result code was 0
else
    : # ... things which should happen otherwise
fi
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

if read thing
    case $thing in
      '' | 'quit') false;;
      *) true;;
    esac
then ...
Run Code Online (Sandbox Code Playgroud)

但实际上,你很少在if语句中看到多个命令(尽管它并不是闻所未闻;你的复合语句||就是一个很好的例子!)

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

  • 尼特挑:“if”语法实际上是“if 命令列表”;then` 和最后一个命令确定状态。并且*命令*可能是一个管道。 (2认同)