为什么以下if
语句成功?
if $(ps aux | grep -q "bla bla") ; then echo "found" ; fi
答案 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