为什么“如果$(ps aux | grep ...)”总是在Bash中成功?

时间:2012-01-22 23:01:27

标签: bash if-statement

为什么以下if语句成功?

if $(ps aux | grep -q "bla bla") ; then echo "found" ; fi

5 个答案:

答案 0 :(得分:34)

因为grep正在返回ps进程本身。你可以通过围绕一个不改变功能的字符类grep中的一个搜索字符来“欺骗”[ ]以使自己不匹配: 只是做:

if ps aux | grep -q "[b]la bla" ; then echo "found" ; fi

此外,不需要使用进程替换$()if将对管道链中最后一个命令的成功起作用,这就是你想要的。

注意:字符类技巧起作用的原因是因为ps输出仍然具有字符类括号,但当grep处理搜索字符串时,它使用括号作为语法而不是匹配的固定字符串。

答案 1 :(得分:8)

如果从ps aux grep输出,您将始终获得显示上一个命令的进程。要解决此问题,您可以将输出管道输出两次grep,一次删除其中包含“grep”的行,再次针对您要查找的过程。

ps aux | grep -v "grep" | grep "Finder"

答案 2 :(得分:7)

'ps'运行时,'grep'进程已经运行,因此ps输出包括它。

请尝试使用pgrep

pgrep正是出于这个目的:

if pgrep "bla bla" ; then echo "found" ; fi

答案 3 :(得分:2)

$(有点相关,稍微改变了一下意思。虽然在这种情况下,因为grep -q从来没有任何输出,所以你可以轻松获得$(。你可能想从类似的东西开始(正如其他人指出的那样):

if ps aux | grep -v 'grep' | grep -q 'bla bla'; then
    echo 'Found'
fi

无论如何,你从

开始
if $(ps aux | grep -q "bla bla") ; then echo "found" ; fi

使用$(,执行$( )内的命令,并将该命令的输出用作外部命令的命令行。做这四个实验:

# if $(echo nonexistant ; true) ; then echo "found" ; fi
nonexistant: command not found

# if $(echo nonexistant ; false) ; then echo "found" ; fi
nonexistant: command not found

# if $(echo  ; true) ; then echo "found" ; fi
found

# if $(echo  ; false) ; then echo "found" ; fi

所以,根据这个,如果这两个条件成立,你将输出get found

  • $( )内的命令创建了无输出
  • 该命令是成功的

这表明ps aux | grep -q "bla bla"成功并且没有输出。 grep -q没有创建输出就不足为奇了。这就是-q的用途。因此,您的命令必须具有真实状态,这意味着grep确实成功找到了匹配项。我们知道grep在这种情况下始终会找到匹配项,因为ps中的流程列表将包含grep本身; grep总能找到自己。

答案 4 :(得分:1)

您需要为'bla bla'过滤掉grep ping的过程:

$ if ps aux | grep -v 'grep' | grep -q 'bla bla'; then
    echo 'Found'
fi