如何使用grep并在特定输出上失败if语句?

10

我需要找到一个命令的输出结果,特别是“gbak:ERROR”,并在其上失败。我不知道我是否正确地处理了它,我试图使grep输出到/dev/null,但我也无法使其工作(可能只是语法错误)。我相信这是一个简单的问题,请告诉我。

我目前拥有的if语句是:

if [ `sudo -u firebird $GBAK_COMMAND | grep "gbak: ERROR"` == *gbak: ERROR* ]; then
   echo "$DATE Unsucessful $1.gdb Gbak. Incorrect user/password" >> /var/log/messages
   echo "Failed"
   exit 1
else
   echo "pass"
fi

2
不要使用已被弃用的反引号,而应该始终使用 $(...)。它更易读,与字体无关,并且您可以轻松地嵌套它 a=$(b $(c $(d)) $(e)) - user unknown
1个回答

12
你不需要使用“test”操作符的方括号;只需测试grep的退出状态即可:
if sudo -u firebird $GBAK_COMMAND | grep -q "gbak: ERROR"
then
   echo "$DATE Unsuccessful $1.gdb Gbak. Incorrect user/password" >> /var/log/messages
   echo "Failed"
   exit 1
else
   echo "pass"
fi

grep-q 选项可以抑制所有输出(适用于 POSIX 和 GNU 变体),因此您只会得到状态,可以将其用于 if 测试。如果 grep 找到了模式,则返回成功,这意味着 firebird 命令失败了。唯一的问题是,“firebird 是否将其错误写入标准输出还是标准错误?” 如果需要重定向标准错误,请写成:

if sudo -u firebird $GBAK_COMMAND 2>&1 | grep -q "gbak: ERROR"
then
   echo "$DATE Unsuccessful $1.gdb Gbak. Incorrect user/password" >> /var/log/messages
   echo "Failed"
   exit 1
else
   echo "pass"
fi

2
对于GNU grep,您可能想要使用-q而不是/以及-s(GNU的-s仅抑制有关无法读取文件等的投诉,而不是匹配的行)。 - Jeremiah Willcock
干得好,谢谢!我已经修复了,没有问题。是的,非常有趣,如果我没有加上2>&1,它会直接跳过,好像什么都没发生一样。我需要学习一下这个标准错误的东西,因为我对它不太了解,也不知道它是做什么用的。 - edumike
@Jeremiah:是的,你说得对;而且不仅仅是GNU grep,还有POSIX。我会修改答案的 - 谢谢。 - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接