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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36371221/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 14:27:23  来源:igfitidea点击:

Checking the success of a command in a bash `if [ .. ]` statement

bashif-statement

提问by Abhinandan Aithal

I am trying to automate our application backup. Part of the process is to check the exit status of egrepin an ifstatement:

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

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

I expected it to output testingbecause the file exists and egrepreturns success, but instead I'm getting an error:

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

-bash: [: too many arguments

I tried with all kinds of syntax - additional brackets, quotes etc but error still persists.

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

Please help me in understanding where I am going wrong.

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

回答by tripleee

You are making the common mistake of assuming that [is part of the ifstatement's syntax. It is not; the syntax of ifis simply

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

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

One of the common commands we use is [which is an alias for the command test. It is a simple command for comparing strings, numbers, and files. It accepts a fairly narrow combination of arguments, and tends to generate confusing and misleading error messages if you don't pass it the expected arguments. (Or rather, the error messages are adequate and helpful once you get used to it, but they are easily misunderstood if you're not used.)

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

Here, you want to check the result of the command egrep:

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

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

In the general case, commandcan be a pipeline or a list of commands; then, the exit code from the final command is the status which ifwill examine, similarly to how the last command in a script decides the exit status from the script.

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

These compound commands can be arbitrarily complex, like

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

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

but in practice, you rarely see more than a single command in the ifstatement (though it's not unheard of; your compound statement with ||is a good example!)

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

Just to spell this out,

只是为了说明这一点,

if [ egrep foo bar ]

is running [aka teston the arguments egrep foo bar. But [without options only accepts a single argument, and then checks whether or not that argument is the empty string. (egrepis clearly not an empty string. Quoting here is optional, but would perhaps make it easier to see:

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

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

This is obviously silly in isolation, but should hopefully work as an illustrative example.)

孤立地看这显然是愚蠢的,但希望可以作为一个说明性的例子。)

The historical reasons for testas a general kitchen sink of stuff the authors didn't want to make part of the syntax of ifis one of the less attractive designs of the original Bourne shell. Bash and zshoffer alternatives which are less unwieldy (like the [[double brackets in bash), and of course, POSIX testis a lot more well-tempered than the original creation from Bell Labs.

test作为一般厨房水槽,作者不想将其作为语法的一部分的历史原因if是原始 Bourne shell 不太吸引人的设计之一。Bash 并zsh提供不那么笨拙的替代方案(如[[bash 中的双括号),当然,POSIXtest比贝尔实验室的原始创造要好得多。

回答by Baptiste

This works : put your egrep into "$()", remove -q and make a string comparison :

这有效:将您的 egrep 放入“$()”,删除 -q 并进行字符串比较:

if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] ||
   [ "$(egrep -i 'error|warning|fatal|missing|critical' $File)" != "" ];
then

   echo "testing";

fi