我正在尝试自动化我们的应用程序备份。该过程的一部分是在 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/