ps aux | 带点的 grep

ps aux | 带点的 grep

我正在尝试编写一个脚本来查找正在运行的进程。

我试图避免实际的 grep 从ps aux输出中返回。

但是,如果我使用点或不使用点,我会得到不同的结果:

ps aux | grep [s]elenium不返回任何内容。

ps aux | grep [s]elenium.jar返回 grep 命令:

beebee   36155  0.0  0.0  15940   956 pts/0    S+   16:20   0:00 grep --color=auto selenium.jar

这是为什么?

答案1

我猜你当前文件夹中有一个名为的文件selenium.jar,但没有调用的文件。selenium

如果你跑

 ps aux | grep [s]elenium.jar

shell 将尝试用当前文件夹中的匹配文件名进行替换。如果存在匹配的[s]elenium.jar文件,则将其替换为。selenium.jar[s]elenium.jarselenium.jar

然后 shell 将使用替换的值执行命令,即

ps aux | grep selenium.jar

为了避免这种情况,引用正则表达式来保护它免受外壳的侵害:

ps aux | grep '[s]elenium.jar'

答案2

这里的问题,正如@Florian 敏锐地想通了,是 shell 先将搜索字符串中的 glob 字符扩展为匹配的文件名,然后再将该字符串传递给grep

运行ps aux | grep foo是有问题的,因为grep foo命令本身会匹配foo,因此会出现在输出中。有两种常见的解决方法,虽然有些复杂。您可以grep -v grep在管道末尾添加一个,或者使用grep [f]oo。由于grep适用于正则表达式,它将被视为[f]“括号内字符列表中的任何字符”。由于括号中唯一的字符是f[f]oo因此等同于foo。但是,结果grep中显示的过程ps将具有细绳 [f]oo因此,无法被找到grep

如果您的当前目录中有一个名为的文件(您的情况似乎如此),情况会变得更加复杂。foo由于您没有引用您给出的表达式grep(因为您使用了[s]eleniumand 而不是'[s]elenium'or "[s]elenium"),因此 shell 会将其视为全局并将其展开为匹配的文件名。这使得这个[s]elenium技巧变得毫无用处,因为实际传递给的grepselenium,而不是[s]elenium,所以 grep 会匹配自身。

然而,这一切的发生都是因为你没有使用正确的工具。通常情况下,有一个应用程序可以解决这个问题!不要使用grep+ ps。相反,使用pgrep专为您想要的功能而设计的应用程序:

NAME
       pgrep,  pkill  -  look  up  or signal processes based on name and other
       attributes

SYNOPSIS
       pgrep [options] pattern
       pkill [options] pattern

DESCRIPTION
       pgrep looks through the  currently  running  processes  and  lists  the
       process IDs which match the selection criteria to stdout.  All the cri‐
       teria have to match.  For example,

         $ pgrep -u root sshd

因此,就你的情况而言,你可以这样做

pgrep selenium

或者,由于您通过 运行它java,因此使用-fwhich 搜索整个命令行:

pgrep -f selenium

答案3

您可以排除“grep”之后最初的grep:

ps aux | grep '[s]elenium.jar' | grep -v grep

相关内容