一、killall简介
与kill不同的是,killall可以根据进程名来杀死进程,不像kill,可能先需要使用ps(可以参考《ps命令实例详解》)找到进程id,然后发送信号,就像下面这样:
[root@localhost ~]# ps -ef|grep hello
root 15530 6335 0 14:55 pts/4 00:00:00 ./hello
[root@localhost ~]# kill -9 15530
使用killall 接进程名,直接kill掉:
[root@localhost ~]# killall hello
而且由于killall是根据名称杀死进程,因此如果当前运行着大量的hello程序,那么可以一次性杀死所有hello程序。
除此之外,它还有很多参数,例如忽略大小写,根据模式匹配进程名,杀死某个时间的进程等等。
二、killall (no process find) 演示
自己编写了一个(cp显示进度条)程序,尝试使用killall杀死正在运行的这个程序。
[root@localhost scripts]# vim kill_all
#!/bin/bash
# 编写脚本,显示进度条
jindu(){
while :
do
echo -n '#'
sleep 0.2
done
}
jindu &
cp -a $1 $2
killall $0
echo "拷贝完成"
echo "$0"
[root@localhost scripts]# chmod +x kill_all
[root@localhost scripts]# dd if=/dev/zero of=500M_file bs=1M count=500
运行结果:
从脚本跟结果看,$0是获取的脚本的名字,执行killall $0 报错 no process found
ok,那我们ps -ef 查看一下:
直接killall ps查询的进程名字,根本不行找不到进程:
三、killall 原理
killall 为什么不能找不到ps后的进程名,这时候我们用到 strace命令,看看killall杀死一个普通进程到底做了哪些事情:
[root@localhost ~]# yum install strace -y
[root@localhost ~]# strace killall "sh kill_all 500M_file 500M_file_bak2"
打印结果很多,我只提取了部分,可以看到的是,killall会去proc文件系统(proc文件系统可以参考《Linux中不可错过的信息宝库》)下查找各个进程id下的stat文件和cmdline,stat文件是怎样的呢?
从ps 中获取sh kill_all 500M_file 500M_file_bak2 的 pid为103532
查看103532的stat
查看到其实pid是103532的进程名是sh,这就为什么killall sh kill_all 500M_file 500M_file_bak2 提示找不到
查看./kill_all 500M_file 500M_file.bak 的pid的name,发现是kill_all,而$0是./kill_all
因为sh进程名面积太大,所以如果不想修改内核参数,只能用./方式,修改脚本
#!/bin/bash
# 编写脚本,显示进度条
jindu(){
while :
do
echo -n '#'
sleep 0.2
done
}
jindu &
cp -a $1 $2
echo "拷贝完成"
killall `echo "$0"|sed -e s'/.\/\(.*\)/\1/'`