2012-01-22 33 views
23

为什么以下if声明成功?

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

如果您运行'ps aux | grep“bla bla”'你会看到为什么... –

+0

另请参见[这个问题](http://stackoverflow.com/questions/8965887/command-substitution-in-if-statement-condition)。 –

+3

'if pgrep -f“bla bla”;然后回声“发现”; fi' – jordanm

回答

32

因为grep进程本身正在由ps返回。你可以在“绝招” grep不被周围的字符类[ ]搜索字符,不改变功能的一场比赛本身: 只是做:

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

而且,使用过程中替代$()是不必要。 if将在管道链上最后一个命令的成功工作,这是你想要的。

:字符类招工作的原因是因为ps输出仍然有字符类括号但当grep正在处理搜索字符串,它使用了括号的语法,而不是一个固定的字符串相匹配。

+0

go go gadget downvoter – SiegeX

+0

有一个序列downvoter在那里..:P –

+0

好戏法!谢谢! –

7

'grep'进程在ps运行时已经运行,所以ps输出包含它。使用pgrep代替。

p纤ep也正是为了这个目的:

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

+0

Downvoter先生,我已经编辑了我的答案以获得更好的清晰度。请看看现在看起来好多了。 Ta – laher

1

您需要过滤掉的过程,是grep平为“喇嘛喇嘛”:

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

难道你不想在目标grep之后使用-v grep吗? (如果我倒下,我说为什么)。 – shellter

+0

我也没有任何解释就下了两次。我认为有人在这个问题上非常宽松地... ... – laher

+0

@ amir75:看起来喜欢所有的downvotes已经消失(再次没有解释!);-)祝你好运。 – shellter

8

如果使用grep命令从输出ps aux,您将始终获得显示您以前的命令的过程。为了解决这个问题,你可以将输出传递给grep两次,一次删除其中包含“grep”的行,再一次找到你要找的进程。

 
ps aux | grep -v "grep" | grep "Finder" 
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 

因此,根据这一点,你就会输出得到found如果这两个条件都成立:

  • 命令里面的$()创建任何输出
  • 命令是成功的

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

+0

不错的'爆炸'解释发生了什么。 – shellter

相关问题