我正在尝试编写一个脚本来查找正在运行的进程。
我试图避免实际的 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.jar
selenium.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]elenium
and 而不是'[s]elenium'
or "[s]elenium"
),因此 shell 会将其视为全局并将其展开为匹配的文件名。这使得这个[s]elenium
技巧变得毫无用处,因为实际传递给的grep
是selenium
,而不是[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
,因此使用-f
which 搜索整个命令行:
pgrep -f selenium
答案3
您可以排除“grep”之后最初的grep:
ps aux | grep '[s]elenium.jar' | grep -v grep