我有点困惑为什么新鲜的Yosemite 10.10.5似乎有一个nginx进程。
如果我发出命令ps ax | grep "nginx"
或ps aux|grep nginx
我得到:
1266 s000 R+ 0:00.00 grep nginx
几秒钟后ps ax | grep "nginx"
返回:
1280 s000 R+ 0:00.00 grep nginx
如果我尝试:
ps -lef|grep -i nginx:|awk '{ print $2}'|xargs kill -9
我得到:
kill: 1291: No such process
该进程总是在关闭并开启一个新的进程。
活动监视器未显示任何 nginx 进程。
这是正常的吗?为什么我在全新安装 OS X 时会出现这种情况?
答案1
这是完全可以预料到的行为,但如果你不知道所涉及的命令到底起什么作用,可能会有点困惑。不,不存在任何恶意软件。我将尽力解释这里到底发生了什么。
首先,当您运行时ps ax
,它会为您提供系统上运行的所有进程的列表,以及(部分)它们的命令行参数。
其次,当您运行grep "nginx"
它时,它将从其标准输入读取(因为您没有提供用作输入的文件)并输出包含字符串的任何行nginx
。
在类 Unix 系统(如 Mac OS X)的 shell 中,管道的实现方式一般是这样的:命令从右到左开始,但数据传输从左到右。
因此,发生了以下事情:第一个进程grep
以 为参数启动nginx
。第二个进程ps
以 为参数启动ax
,其标准输出与进程的标准输入绑定grep
。ps
运行时,其输出被馈送到 的标准输出ps
,即一样的东西作为 的标准输入grep
。依次grep
查看每一行,查找字符串nginx
,因为这是您grep
要执行的操作。这样的行出现一次:grep 进程本身及其命令行参数!因此,此行由grep
to打印grep 的标准输出,其他所有输出均被抑制。在第一个示例中,grep 的标准输出不与任何其他进程绑定,因此默认情况下会将其打印到终端。当没有更多来自 的数据时ps
,grep
也会退出,因为所有命令都绑定在一起;当其中一个命令完成时,另一个命令执行没有任何实际意义。
当您将 grep 的输出通过管道传输awk
到xargs kill
时,xargs 会构建一个要执行的操作列表,但实际上直到最后才执行。因此,当 xargs 开始调用 kill 时,grep 进程(其命令行参数中包含 nginx)已经消失。因此没有进程可以发送信号并kill
通知您这一事实。
如您所见,您的系统上没有运行任何恶意 nginx 进程来逃避您的查找尝试;只有 grep 会重复启动,每次您查找时都会启动一次,然后查找自身。
您可以通过在搜索字符串的某个位置使用字符组来避免这种情况,因为 不会找到自己。例如,ps ax | grep foobar
返回 grep 进程,但ps ax | grep 'fooba[r]'
不返回,因为与纯字符串进行比较时fooba[r]
不一样。(匹配任何一个字符,因此只有。)请注意,为了做到这一点,您可能必须将参数转义为。foobar
[r]
r
r
grep
另外,几乎总是没有必要先运行grep
,然后awk
中间不做任何其他事情。您可以简单地使用来让 awk 执行两个任务,而不是... | grep 'foobar' | awk '{ print $2 }'
执行某些前面的命令。这在 中最常见,其中它被调用...
... | awk '/foobar/ { print $2 }'
cat
猫的无用用途,但这个概念也可以很好地推广到其他命令,例如您例子中的 grep。
答案2
您没有安装 nginx /将其作为进程运行。
你可以用一些完全虚构的东西替换 nginx 并获得相同的结果:
ps ax | grep "boatymcboatface"