为什么“如果 $(ps aux | grep ...)”在 Bash 中总是成功?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8965509/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why "if $(ps aux | grep ...)" always succeeds in Bash?
提问by Misha Moroshko
Why the following if
statement succeeds ?
为什么下面的if
语句成功?
if $(ps aux | grep -q "bla bla") ; then echo "found" ; fi
回答by SiegeX
Because the grep
process itself is being returned by ps
. You can "trick" grep
to not match itself by surrounding one of the search characters in a character class [ ]
which doesn't change the functionality:
Just do:
因为grep
进程本身由ps
. 您可以grep
通过在[ ]
不改变功能的字符类中包围搜索字符之一来“欺骗”以使其不匹配:只需执行以下操作:
if ps aux | grep -q "[b]la bla" ; then echo "found" ; fi
Also, the use of process substitution $()
is unnecessary. The if
will work on the success of the last command in the pipe chain, which is what you want.
此外,$()
不需要使用进程替换。在if
将在最后一个命令在管道链,这是你想要的成功合作。
Note: The reason the character class trick works is because the ps
output still has the character class brackets but when grep
is processing the search string, it uses the brackets as syntax rather than a fixed string to match.
注意:字符类技巧起作用的原因是因为ps
输出仍然具有字符类括号,但是在grep
处理搜索字符串时,它使用括号作为语法而不是固定字符串进行匹配。
回答by laher
the 'grep' process is already running by the time ps runs, so the ps output includes it.
到 ps 运行时,'grep' 进程已经在运行,因此 ps 输出包含它。
Try using pgrep
instead.
尝试使用pgrep
。
pgrep is precisely for this purpose:
pgrep 正是为此目的:
if pgrep "bla bla" ; then echo "found" ; fi
if pgrep "bla bla" ; then echo "found" ; fi
回答by Sonic84
If you grep the output from ps aux
, you will always get a process showing your previous command. To fix this, you can pipe the output to grep twice, once to remove line with "grep" in it, and again for the process your looking for.
如果您 grep 的输出ps aux
,您将始终得到一个显示您之前命令的进程。要解决此问题,您可以将输出通过管道传递给 grep 两次,一次删除其中包含“grep”的行,再次删除您要查找的过程。
ps aux | grep -v "grep" | grep "Finder"
回答by Aaron McDaid
The $(
is a small little bit relevant, and changes the meaning a bit. Although in this case, because there is never any output from grep -q
, you can just about get away with the $(
. You probably want to start with something like (as pointed out by others):
本$(
是一个小点点相关,并且改变了意思了一下。尽管在这种情况下,因为 从来没有任何输出grep -q
,所以您几乎可以摆脱$(
. 您可能想从以下内容开始(正如其他人指出的那样):
if ps aux | grep -v 'grep' | grep -q 'bla bla'; then
echo 'Found'
fi
Anyway, you started with
无论如何,你开始于
if $(ps aux | grep -q "bla bla") ; then echo "found" ; fi
With $(
, the command inside the $( )
is executed and the output of that command is used as the command line for the outer command. Do these four experiments:
使用$(
,执行内部命令,并且该命令$( )
的输出用作外部命令的命令行。做这四个实验:
# 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
So, according to this you will output get found
if both these conditions hold:
因此,found
如果这两个条件都成立,您将根据此输出 get :
- The command inside the
$( )
created no output - andthe command was succesful
$( )
创建的命令里面没有输出- 并且命令成功
This suggests that ps aux | grep -q "bla bla"
was successful and created no output. It's no surprise that grep -q
creates no output. That's what the -q
is for. So therefore, your command must have had a true status, which implies that the grep did successfully find a match. We know that grep
will always find a match in this case, because the list of processes from ps
will include grep
itself; the grep will always find itself.
这表明这ps aux | grep -q "bla bla"
是成功的并且没有产生任何输出。不grep -q
产生任何输出也就不足为奇了。这就是-q
它的用途。因此,您的命令必须具有 true 状态,这意味着 grep 确实成功找到了匹配项。我们知道grep
在这种情况下总是会找到匹配项,因为来自的进程列表ps
将包含grep
自身;grep 总会找到自己。
回答by Johnsyweb
You need to filter out the process that is grep
ping for 'bla bla':
您需要过滤掉正在grep
ping 'bla bla'的进程:
$ if ps aux | grep -v 'grep' | grep -q 'bla bla'; then
echo 'Found'
fi