grep - 以 1 退出 - 如果匹配

Ale*_*lls 7 grep bash shell-script

我有一个像这样的 bash 函数:

run_mongo(){
  mongo foo bar baz 2>&1  # send stderr to stdout
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,如果出现错误,这个 mongo 命令不会以 1 退出,所以我必须匹配 stdout/stderr

如果有第一个匹配项,是否有某种方法可以使用 grep 以代码 > 0 退出?像这样:

run_mongo | grep -e "if stdout/stderr matches this we exit with 1"
Run Code Online (Sandbox Code Playgroud)

我假设这样做的方法是这样的:

run_mongo | grep -e "if stdout/stderr matches" | killer
Run Code Online (Sandbox Code Playgroud)

其中killer 是一个程序,它会在获得第一个stdin 后立即终止。

ter*_*don 10

是的,您可以使用grep -vzwhich tellgrep来查找与您提供的模式不匹配的行 ( -v) 并立即读取整个 ionput ( z),这样一个匹配就意味着整个过程失败:

$ printf 'foo\nbar\n' | grep -zqv foo && echo no || echo yes
yes
$ printf 'foo\nbar\n' | grep -zq foo && echo no || echo yes
no
Run Code Online (Sandbox Code Playgroud)

所以,在你的情况下,类似于:

run_mongo(){
  mongo foo bar baz 2>&1 | grep -vzq "whatever means failure" 
}

if run_mongo; then
 echo "Worked!"
else
  echo "Failed!"
fi
Run Code Online (Sandbox Code Playgroud)

如果您想避免读取整个输出,只需使用其他工具。Perl,例如:

mongo foo bar baz 2>&1 | perl -ne 'exit 1 if /whatever means failure/' 
Run Code Online (Sandbox Code Playgroud)


Kus*_*nda 5

如果您需要尽快终止:

run_mongo () {
    ! mongo foo bar baz 2>&1 | grep -q 'bad-pattern'
}
Run Code Online (Sandbox Code Playgroud)

如果在输出中找到该模式,这将mongo尽快运行并终止该函数。bad-pattern当模式匹配时,grep立即退出,并mongo在尝试写入死管道时立即接收 PIPE 信号。

由于!,管道的退出状态将被反转,即,如果未找到模式,则退出状态为零;如果找到,则退出状态为非零。

如果您需要让其mongo完成写入输出:

run_mongo () {
    ! mongo foo bar baz 2>&1 | grep 'bad-pattern' > /dev/null
}
Run Code Online (Sandbox Code Playgroud)

这与此答案中的第一段代码相同,但grep现在消耗mongo.