使用grep命令过滤进程时,如何消除grep本身进程的影响
你是否也遇到了跟我同样的问题: 使用 grep 命令过滤并统计一个进程出现的次数,如下所示:
[root@lb01~ ]#ps -ef | grep nginx
root 20239 1 0 Jul06 ? 00:00:00nginx: master process /usr/sbin/nginx-c /etc/nginx/nginx.conf
nginx20240 20239 0 Jul06 ? 00:00:00nginx: worker process
root 22343 22252 0 17:55 pts/0 00:00:00 grep --color=autonginx
此时我们看到的“貌似”是 nginx 在系统中有3个进程,然后统计一下:
[root@lb01~ ]#ps -ef | grep nginx |wc -l
3
“应该是”3个进程没毛病啊?我一开始的确是这么认为的……
然后我就把这条命令放入脚本中了,截个图吧:

一个简单的不完善的脚本,后面又改动了,大神憋说话~
当 nginx 正常有 “3” 个进程时,系统不应理会这条命令才对,可是我一执行脚本,我的 keepalived 服务就被系统无情 stop了 !!!
那我肯定不服啊对不对!必须找出问题所在!
检查脚本,觉得没什么问题。重启服务再执行脚本,来来回回几次毒打之后,i 服了系统了~不过也让我发现了一个问题:
[root@lb01~ ]#ps -ef |grep nginx |wc -l
3
[root@lb01~ ]#info=`ps -ef |grep nginx |wc -l`
[root@lb01~ ]#echo $info
2
这是什么情况? 欺负人?
好了,到这里才到这篇博客的主题,如果你还在看的话,等我喝口水继续讲~
- 日常操作linux 中,通常在使用 ps命令后 用管道连接 查询特定进程会显示 grep 进程本身。
如下:
[root@lb01~ ]#ps -ef |grep abcdefg
root 22445 22407 0 18:48 pts/1 00:00:00 grep --color=autoabcdefg
[root@lb01~ ]#ps -ef |grep abcdefg
root 22457 22407 0 18:54 pts/1 00:00:00 grep --color=autoabcdefg
[root@lb01~ ]#ps -ef |grep abcdefg
root 22459 22407 0 18:54 pts/1 00:00:00 grep --color=autoabcdefg
[root@lb01~ ]#ps -ef |grep sshd
root 7106 1 0 Jul03 ? 00:00:00 /usr/sbin/sshd-D
root 22250 7106 0 16:55 ? 00:00:00sshd: root@pts/0
root 22405 7106 0 18:38 ? 00:00:00sshd: root@pts/1
root 22448 22407 0 18:48 pts/1 00:00:00 grep --color=autosshd
上面执行的四次命令总结为两点:
- 可以看到,不论你要查找的进程是否存在,本身都会产生一个 grep 的进程。
- 拿上面的 “abcdefg” 来说,系统中是没有这个进程的,但是你每次执行命令后都会跑出来一行内容( grep 进程)。而且注意到没有:每次出现的 grep 进程的 PID(标记为黄色)都是不一样的,这说明它并不是一个守护进程!它只是个 ‘临时演员’!
- 这一点是临时起意加的,不另收费 (xīxīxī ☺):那个 grep 的进程我看就是给它要过滤的字符串标记颜色的 --color=auto ,它要过滤‘什么内容’,那么‘
什么内容’就会被标记颜色。要是说的不对欢迎大佬在评论区给我指出,先 3q very much。
- 到这我们应该能明白最开始遇到的问题所在了:系统执行脚本的时候,并没有把 grep那个进程算进去(就是说没有把这位‘临时演员’当人看,你说气不气人~),所以脚本中的 $info -lt 3 自然是成立的,所以我的 keepalived 进程被人家停的是理直气壮啊。
来吧,解决方法如下:
方法一:
- 利用 grep 的参数 -v 取反:
[root@lb01~ ]#ps -ef |grep nginx |grep -v grep
root 20239 1 0 Jul06 ? 00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx 20240 20239 0 Jul06 ? 00:00:00 nginx: worker process
这个好理解吧,就是过滤出需要的进程后 再过滤一下 grep本身进程并取反。
方法二:
- 利用 pgrep 命令
pgrep 是通过程序的名字来查询进程的工具,一般是用来判断程序是否正在运行。
[root@lb01~ ]#pgrep nginx
20239
20240
[root@lb01~ ]#pgrep -l nginx
20239 nginx
20240 nginx
-l 参数:列出进程id和程序名,不加参数只显示进程id。
pgrep 命令更方便快捷,但是它的缺点你也看到了吧,只显示进程pid,所以他到底香不香呢,你自己考虑咯~
方法三:
- 利用 grep的正则表达符号 [ ]
[root@lb01~ ]#ps -ef |grep [n]ginx
root 20239 1 0 Jul06 ? 00:00:00nginx: master process /usr/sbin/nginx-c /etc/nginx/nginx.conf
nginx20240 20239 0 Jul06 ? 00:00:00nginx: worker process
在这三种方法里面,第三种是我花最长时间理解的了
周末我就滚去复习三剑客正则,我不保证 o( ̄▽ ̄)d
那为什么加个[ ]就能达到我们想要的效果,把 grep本身进程过滤掉呢?
a. 机智如你 估计已经有了答案了,那么是时候跟这篇博文say byebye了
想想还有点小不舍呢~
红颜弹指老,刹那芳华,与其天涯思君,恋恋不舍,莫若相忘于江湖。
——《天龙八部》
b. 能坚持看到这里,说明你也是虚心好学之人,那咱们一起看一看吧~
准备工作:
[root@lb01~ ]#cat -n test.txt
1 grep --color=auto nginx
2 grep --color=auto [n]ginx
上面的文件中有两行内容
- 用 grep命令过滤出第1行内容:grep nginx test.txt
方法很多,这儿就不说了; - 用 grep命令过滤出第2行内容:?
如果我们用的是下面这种方法:
[root@lb01~ ]#grep [n]ginx test.txt
grep --color=autonginx
看到了什么?明明过滤的是 [n]ginx,为什么过滤出来的结果是 nginx ?明明一脸懵逼( ̄. ̄)
其实这不就是上面的方法三吗,说了一堆废话呀…
您再忍忍,先别吐槽我。我直接上结论:
- 在正则表达式中,[ ] 表示匹配指定范围内的任意单个字符,
那么[n]ginx就表示匹配的是 nginx ,没毛病;
但如果是 [ng]inx ,那么匹配的就是 nginx, gninx, ninx, ginx,学习过正则表达式的你应该比我更清楚呢; - 划重点: 我们用 grep [n]ginx 来匹配时,grep 本身当然也还有个进程,不过那个进程应该是
- grep --color=auto [n]ginx
- ( grep 这个进程显示时 是把命令行的grep 后面所跟的要过滤的所有字符串都显示出来,即 你让我grep 过滤的字符串是 [n]ginx ,那么在我grep 的进程中所显示的就是 [n]ginx )
- 而在命令行的 grep [n]ginx 正则表达式匹配的是 nginx ,
So 到这你应该就明白了吧?
啥?还不太懂?再从头看一遍!
方法四:
- 以我最上面的脚本为例,把数值 3 改成 2 即可。(这个方法就有点取巧了└@(•ェ•)@┐)
小结:
几种方法,挑自己顺手的用就行~
其实有的朋友看博文时,可能想要的答案只是其中某一条,我啰里啰嗦的一堆,实在是有点过瘾呢~~
哈哈哈哈哈哈哈哈哈哈~~
第一次在优快云上发布文章,有写的不好的地方,你就多忍忍叭~~

在Linux环境中,使用grep过滤进程时,会发现grep自身进程也被计入统计。本文通过实例解析如何消除grep影响,包括使用grep的-v参数,pgrep命令,以及正则表达式技巧,确保准确过滤目标进程。
801





