问题在于,正如@Florian敏锐地发现的那样,shell会在将搜索字符串传递给grep之前,将通配符字符扩展为匹配的文件名。
运行"ps aux | grep foo"是有问题的,因为"grep foo"命令本身会匹配"foo",从而出现在输出中。有两种常见但复杂的解决方法。一种是在管道末尾添加"grep -v grep",另一种是使用"grep [f]oo"。由于grep使用正则表达式,它会将"[f]"视为"括号内字符列表中的任意字符"。由于括号内只有一个字符"f","[f]oo"等同于"foo"。然而,在"ps"结果中显示的grep进程将具有字符串"[f]oo",因此无法被grep找到。
这变得更加复杂,如果像你所说的,在当前目录下有一个名为
foo
的文件。因为你没有引用给
grep
的表达式(因为你使用了
[s]elenium
而不是
'[s]elenium'
或
"[s]elenium"
),shell会将其视为
glob并将其扩展为匹配的文件名。这使得
[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
选项来搜索整个命令行。
pgrep -f selenium
java
命令开头。我的方法就是只匹配selenium
字符串,并使用grep -v grep
进行过滤,以去除 grep 命令本身。 - Sergiy Kolodyazhnyy