原标题:Linux pkill和killall命令的缺陷

总结1 :尽量避免使用 killall、pgrep 、ps | xargs kill 的方式

总计2 :尽量使用 pidof 或者 pidof | xargs kill 的组合来代替上面的几个命令

平常大家 kill 进程,可能习惯使用如下的方式

1

killall bt_uinfo_memcached

1

pkill bt_uinfo_memcached

1

ps -C bt_uinfo_memcached -- format ='pid' --noheaders | xargs kill

大部分情况下这个都是可以正常工作的,但我们来看一下下面的这个命令

1

2

3

4

5

6

root@ubuntu:~ # ps -ef |grep bt_uinfo_memcached

root 8765 23103 0 14:13 pts /2 00:00:00 grep --color=auto bt_uinfo_memcached

root 26195 1 0 12:43 ? 00:00:32 . /bt_uinfo_memcached -p 20211 -u root -l 0.0.0.0 -m 3072 -d

root 26236 1 0 12:43 ? 00:00:30 . /bt_uinfo_memcached -p 20311 -u root -l 0.0.0.0 -m 3072 -d

root 26586 1 1 12:43 ? 00:01:15 . /bt_uinfo_memcached -p 20411 -u root -l 0.0.0.0 -m 3072 -d

root@ubuntu:~ #

1

2

3

root@ubuntu:~ # killall bt_uinfo_memcached

bt_uinfo_memcached: no process found

root@ubuntu:~ #

killall 命令竟然找不到 bt_uinfo_memcached 进程? 上面 ps 命令是列出来了的 。换 pkill 试试,还是不行

1

2

3

4

5

6

7

8

root@ubuntu:~ # pkill bt_uinfo_memcached

root@ubuntu:~ #

root@ubuntu:~ # ps -ef |grep bt_uinfo_memcached

root 17723 23103 0 14:19 pts /2 00:00:00 grep --color=auto bt_uinfo_memcached

root 26195 1 0 12:43 ? 00:00:36 . /bt_uinfo_memcached -p 20211 -u root -l 0.0.0.0 -m 3072 -d

root 26236 1 0 12:43 ? 00:00:34 . /bt_uinfo_memcached -p 20311 -u root -l 0.0.0.0 -m 3072 -d

root 26586 1 1 12:43 ? 00:01:22 . /bt_uinfo_memcached -p 20411 -u root -l 0.0.0.0 -m 3072 -d

root@ubuntu:~ #

甚至连 ps 也有问题,当 -C(command) 选项的参数值超过15个字符时,实际上是会匹配到其他的进程

1

2

3

4

5

6

7

8

9

10

11

linbobo@ubuntu:~$ ps -C bt_uinfo_memcachecd

PID TTY TIME CMD

26195 ? 00:01:44 bt_uinfo_memcac

26236 ? 00:01:41 bt_uinfo_memcac

26586 ? 00:03:23 bt_uinfo_memcac

linbobo@ubuntu:~$ ps -C bt_uinfo_memcachecd123456

PID TTY TIME CMD

26195 ? 00:01:44 bt_uinfo_memcac

26236 ? 00:01:41 bt_uinfo_memcac

26586 ? 00:03:23 bt_uinfo_memcac

linbobo@ubuntu:~$

为什么会这样呢? 通过 strace 命令可以找到原因

1

2

3

4

5

6

7

8

9

10

11

12

root@ubuntu:~ # strace -e trace=file pkill bt_uinfo_memcached 2>&1 | grep open | tail

open ( "/proc/31713/status" , O_RDONLY) = 4

open ( "/proc/31713/cmdline" , O_RDONLY) = 4

open ( "/proc/31716/status" , O_RDONLY) = 4

open ( "/proc/31716/cmdline" , O_RDONLY) = 4

open ( "/proc/31717/status" , O_RDONLY) = 4

open ( "/proc/31717/cmdline" , O_RDONLY) = 4

open ( "/proc/31720/status" , O_RDONLY) = 4

open ( "/proc/31720/cmdline" , O_RDONLY) = 4

open ( "/proc/31721/status" , O_RDONLY) = 4

open ( "/proc/31721/cmdline" , O_RDONLY) = 4

root@ubuntu:~ #

pkill 命令检查的是 /proc/ 下面的 pid 目录的 cmdline 文件和 status 文件。我们找其中一个 bt_uinfo_memcached 进程 ( 26195 ) 看一下,

1

2

3

4

5

6

7

root@ubuntu:~ # cat /proc/26195/cmdline | tr '0' ' '

. /bt_uinfo_memcached -p 20211 -u root -l 0.0.0.0 -m 3072 -d root@ubuntu:~ #

root@ubuntu:~ #

root@ubuntu:~ # cat /proc/26195/status | tr '0' ' '

Name: bt_uinfo_memcac

State: S (sleeping)

.....

可以看到 cmdline 是记录完整命令行的 (pgrep 默认是部分匹配),而 status 这个文件里面的 Name 字段的值是 bt_uinfo_memcac 而不是 bt_uinfo_memcached ,也就是被截断了(15个字符,OS 的限制) !!!

虽然 cmdline 文件里面记录的命令是正确的,但我估计 pgrep 会对比 cmdline 第一个字段和 status 文件的 Name 字段的值是否相同,如果不同则跳过,所以虽然 cmdline 是对的,但 pkill 并不杀死该进程

下面再来看 killall 命令的

1

2

3

4

5

6

7

8

9

10

11

12

linbobo@ubuntu:~$ strace -e trace= file killall bt_uinfo_memcached 2>&1 | grep open | tail

open ( "/proc/31705/stat" , O_RDONLY) = 3

open ( "/proc/31708/stat" , O_RDONLY) = 3

open ( "/proc/31709/stat" , O_RDONLY) = 3

open ( "/proc/31712/stat" , O_RDONLY) = 3

open ( "/proc/31713/stat" , O_RDONLY) = 3

open ( "/proc/31716/stat" , O_RDONLY) = 3

open ( "/proc/31717/stat" , O_RDONLY) = 3

open ( "/proc/31720/stat" , O_RDONLY) = 3

open ( "/proc/31721/stat" , O_RDONLY) = 3

open ( "/proc/32553/stat" , O_RDONLY) = 3

linbobo@ubuntu:~$

killall 命令跟 pkill(pgrep) 不同,它查看的不是 /proc/pid/{cmdline,status} 文件,而是另外一个文件 /proc/pid/stat ,这个文件的内容

1

2

3

4

linbobo@ubuntu:~$ cat /proc/26195/stat

26195 (bt_uinfo_memcac) S 1 26195 26195 0 -1 4202560 42735 0 0 0 3517 5339 0 0 20 0 6 0 293270594 475316224

36956 18446744073709551615 1 1 0 0 0 0 0 4097 2 18446744073709551615 0 0 17 9 0 0 0 0 0

linbobo@ubuntu:~$

可以看到也是一样被截断了,所以 killall 没杀死进程就是这个导致的。

把 killall 和 pkill 命令改为下面就可以了

1

2

3

4

5

linbobo@ubuntu:~$ pgrep bt_uinfo_memcac

26195

26236

26586

linbobo@ubuntu:~$

既然如此,那么有没有 可靠一点的命令呢? 有,那就是 pidof命令 。pidof 命令除了查找 cmdline 和 stat 文件外,还查找了 /proc/pid/exe 这个symbol link

所以对于那些二进制名超过 15 个字符,甚至启动后改名的都可以找到, 最常见就是 myshard 的东东

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

open ( "26195/stat" , O_RDONLY) = 4

fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1c95e9d000

read (4, "26195 (bt_uinfo_memcac) S 1 2619" ..., 1024) = 251

close(4) = 0

munmap(0x7f1c95e9d000, 4096) = 0

open ( "26195/cmdline" , O_RDONLY) = 4

fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1c95e9d000

read (4, "./bt_uinfo_memcached0-p000202110-u" ..., 1024) = 60

close(4) = 0

munmap(0x7f1c95e9d000, 4096) = 0

stat( "/proc/26195/exe" , {st_mode=S_IFREG|0755, st_size=325966, ...}) = 0

open ( "26236/stat" , O_RDONLY) = 4

fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1c95e9d000

read (4, "26236 (bt_uinfo_memcac) S 1 2623" ..., 1024) = 250

close(4)

1

2

3

4

5

6

7

8

9

linbobo@ubuntu:~$ ps -ef | grep shard

linbobo 9741 9722 0 14:59 pts /0 00:00:00 grep --color=auto shard

root 27628 1 0 May02 ? 00:27:09 . /shard_2013_115_d

root 27732 1 0 May02 ? 00:16:17 . /shard_2013_116_d

linbobo@ubuntu:~$ pidof shard_2013_115_d

27628

linbobo@ubuntu:~$ sudo ls -l /proc/27628/exe

lrwxrwxrwx 1 root root 0 2013-05-29 16:00 /proc/27628/exe -> /home/dspeak/myshard/2013/room_1_0/bin/shard_d

linbobo@ubuntu:~$ 返回搜狐,查看更多

责任编辑:

linux ps命令缺点,Linux pkill和killall命令的缺陷相关推荐

  1. 一天一个 Linux 命令(37):killall 命令

    本文为joshua317原创文章,转载请注明:转载自joshua317博客 一天一个 Linux 命令(37):killall 命令 - joshua317的博客 一.简介 Linux里的killal ...

  2. Linux ps、top、free、uname命令

    Linux ps.top.free.uname命令 Linux有很多查看系统运行时状态的命令,例如查看进程信息的ps和top,以及查看内存信息的free命令和操作系统信息的uname命令等. ps 全 ...

  3. linux ps查看进程,Linux新手入门:PS命令查看正在运行的进程

    Linux作为开源系统,里面有着大量命令需要了解和使用,同样的命令在不同系统中的使用方法各不相同,例如本次要介绍的PS命令,那么什么是PS命令?要如何使用PS命令?下面小编就跟大家详细讲解Linux ...

  4. linux常用命令(65):killall命令

    killall命令 killall命令使用进程的名称来杀死进程,使用此指令可以杀死一组同名进程. 我们可以使用kill命令杀死指定进程PID的进程,如果要找到我们需要杀死的进程,我们还需要在之前使用p ...

  5. linux ps结果解析,Linux笔记-ps -aux的结果解析

    ps 的参数说明 ps 提供了很多的选项参数,常用的有以下几个: l 长格式输出: u 按用户名和启动时间的顺序来显示进程: j 用任务格式来显示进程: f 用树形格式来显示进程: a 显示所有用户的 ...

  6. linux ps ax tl,Linux常用指令 - osc_wa6fkyf0的个人空间 - OSCHINA - 中文开源技术交流社区...

    空格键    :向下翻动一页: [pagedown]:向下翻动一页: [pageup]  :向上翻动一页: /字符串     :向下搜寻[字符串]的功能: ?字符串     :向上搜寻[字符串]的功能 ...

  7. linux ps和 pstree,Linux ps和pstree命令知识点总结

    Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...

  8. linux ps sleep进程,Linux:ps命令以及进程状态详解

    Linux查看进程PS命令详细介绍 1.ps简介 ps命令就是最根本相应情况下也是相当强大地进程查看命令.运用该命令可以确定有哪些进程正在运行和运行地状态.进程是否结束.进程有没有僵死.哪些进程占用了 ...

  9. linux ps aux tty,linux ps命令中的tty表示什么意思?

    在使用ps aux时,输出有一个字段叫做TTY,想知道它是什么意思,所以就查了一下,这篇文章觉得讲得简单易理解.USER PID %CPU %MEM VSZ RSS TTY STAT START TI ...

最新文章

  1. jQuery方法大全
  2. 什么Linux服务器最适合你?
  3. MVC中实现订单表和订单详细表联动新增的一种方法
  4. 计算机怎么恢复上一步,电脑怎么还原系统 电脑还原系统步骤盘点
  5. 自己编写jQuery插件之表单验证
  6. LeetCode 2039. 网络空闲的时刻(BFS)
  7. Jupyter notebook绘制热力图边缘只有一半的问题
  8. 半路出家学php可以吗,PHP半路出家(1)_PHP教程
  9. Leecode刷题热题HOT100(7)—— 整数反转
  10. DotNetNuke(DNN) 中查询所有管理员的SQL语句
  11. 两台服务器怎么发文件,两台服务器怎么发文件
  12. tcpip路由技术卷一_学网络拿高薪!「纯干货」IELAB路由技术问题总结1
  13. 汉字转拼音首字母大写
  14. 计算机辅助设计课程设计评分标准,CAD考试规则评分标准.doc
  15. UI设计和原型设计的区别
  16. 带宽、峰值带宽,网速是什么,它们有什么关系?
  17. isis学不到looback口的路由_无线路由器怎么设置无线桥接 无线路由器设置无线桥接步骤【教程】...
  18. REDIS HGETALL按序输出结果
  19. android 调用搜狗地图api,sogou地图API用法实例教程
  20. postgresql源码学习(45)—— PostmasterMain(2) GUC参数简介及设置

热门文章

  1. jvm内存与垃圾回收重点总结
  2. JVM运行时数据区之Java堆
  3. 建模实训报告总结_3Dmax建模实习报告
  4. Android—常用热修复框架
  5. [工作]公司报销发票抬头信息
  6. hibernate.dialect oracle,Hibernate Dialect for Oracle 19
  7. Windows10系统使用密钥登录Linux
  8. 私募创业之思勰:走到最后留下的还是价值观一致的人
  9. [转]这么教你一定能懂!用饮水机教你什么是RAID
  10. 密集假目标 Matlab,作战雷达发射假目标干扰信号优化匹配仿真