之前只知道kill、killall命令,能杀死进程就行,有些进程杀不死的也不知道为何,今天看书发现出来kill、killall命令,还有一个pkill命令,详细看了下他们的介绍和使用。

kill杀进程的工作原理

首先了解下kill为何能杀死进程,信号是Linux中的一种进程间通信机制,我们可以使用特定的信号来中断进程。每一种信号都同一个整数值相关联。当进程接收到一个信号时,它会通过执行对应的信号处理程序(signal handler)来进行响应。kill命令可用来向进程发送信号,而trap命令用来处理所接收的信号。
(ctrl+c、ctrl+z也会发出各自的信号)

kill

信号编号

[root@server ]# kill -l     #打印出信号编号以及对应信号名称
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX 

kill终止进程方式

 -s, --signal signal
 	Specify the signal to send.  The signal may be given as a signal name or number.
-l, --list [signal]
 	Print a list of signal names, or convert signal given as argument to a name.  The signals are found in /usr/include/linux/signal.h
-L, --table
	Similar to -l, but will print signal names and their corresponding numbers.
-a, --all
	Do not restrict the commandname-to-pid conversion to processes with the same uid as the present process.
-p, --pid
	Specify that kill should only print the process id (pid) of the named processes, and not send any signals.
-q, --queue sigval
	Use sigqueue(2) rather than kill(2) and the sigval argument is used to specify an integer to be sent with the signal.  If the receiving process has installed a handler for this signal using the  SA_SIGINFO,flag to sigaction(2), then it can obtain this data via the si_value field of the siginfo_t structure.
kill PROCESS_ID_LIST

LISTkill命令默认发出一个TERM信号,对照信号编号看,应该为15。进程ID列表使用空格作为进程ID之间的定界符。下面试下kill及kill -15:

[root@server ~]# md5sum /dev/zero &
[1] 14652
[root@server ~]# md5sum /dev/zero &
[2] 15978
[root@server ~]# kill 14652 15978
[1]-  已终止               md5sum /dev/zero
[2]+  已终止               md5sum /dev/zero
[root@server ~]# md5sum /dev/zero &
[1] 23550
[root@server ~]# md5sum /dev/zero &
[2] 23592
[root@server ~]# kill -15 23550 23592
[1]-  已终止               md5sum /dev/zero
[2]+  已终止               md5sum /dev/zero

发现都终止了进程,感觉有点可信,不过可以终止进程的信号编号不止15,还有其他,信不信也关系不大;

kill -s SIGNAL PID

参数SIGNAL要么是信号名称,要么是信号编号。尽管有很多信号可用于不同的目的,但经常用到的其实只有那么几个,具体如下所示。
□ SIGHUP 1——对控制进程或终端的终结进行挂起检测(hangup detection)。
□ SIGINT 2——当按下Ctrl+C时发送该信号。
□ SIGKILL 9——用于强行杀死进程。
□ SIGTERM 15——默认用于终止进程。
□ SIGTSTP 20——当按下Ctrl+Z时发送该信号。

我们经常要强行杀死进程,可以使用:$ kill-s SIGKILL PROCESS_ID(与kill-9 PROCESS_ID等效)

[root@server ~]# md5sum /dev/zero &
[1] 18708
[root@server ~]# md5sum /dev/zero &
[2] 19229
[root@server ~]# kill -s SIGKILL 18708
[1]-  已杀死               md5sum /dev/zero
[root@server ~]# kill -9 19229
[2]+  已杀死               md5sum /dev/zero

linux 的 kill命令是向进程发送信号,-9表示无条件退出,但由进程自行决定是否退出,这就是为什么 kill -9 终止不了系统进程和守护进程的原因。

killall

help
  -e,--exact          require exact match for very long names
  -I,--ignore-case    case insensitive process name match
  -g,--process-group  kill process group instead of process
  -y,--younger-than   kill processes younger than TIME
  -o,--older-than     kill processes older than TIME
  -i,--interactive    ask for confirmation before killing
  -l,--list           list all known signal names
  -q,--quiet          don't print complaints
  -r,--regexp         interpret NAME as an extended regular expression
  -s,--signal SIGNAL  send this signal instead of SIGTERM
  -u,--user USER      kill only process(es) running as USER
  -v,--verbose        report if the signal was successfully sent
  -V,--version        display version information
  -w,--wait           wait for processes to die
  -Z,--context 正则表达式 仅杀死含有指定上下文的进程
                          (必须在其他参数前使用)

killall命令通过命令名终止进程,可以接受信号名称和信号编号;
$ killall process_name

[root@server ~]# md5sum /dev/zero &
[1] 22811
[root@server ~]# ps -ef |grep md5sum
root     22811 19683 99 21:34 pts/5    00:05:57 md5sum /dev/zero
root     28368 19683  0 21:40 pts/5    00:00:00 grep --color=always md5sum
[root@server ~]# killall md5sum
[1]+  已终止               md5sum /dev/zero

$ killall-s SIGNAL process_name通过名称强行杀死进程:

[root@server ~]# md5sum /dev/zero &
[2] 368
[root@server ~]# md5sum /dev/zero &
[2] 26834
[root@server ~]# killall -s SIGKILL md5sum    #同样的名称的进程会被一起杀掉
[1]+  已杀死               md5sum /dev/zero
[2]-  已杀死               md5sum /dev/zero
[root@server ~]# md5sum /dev/zero &
[1] 17233
[root@server ~]# killall -s 9 md5sum   #与killall -s SIGKILL md5sum效果一致
[1]+  已杀死               md5sum /dev/zero

通过名称以及所属用户名指定进程:
$ killall-u USERNAME process_name

[root@server ~]# md5sum /dev/zero &
[1] 31070
[root@server ~]# killall -u root md5sum     #指定用户杀他的进程,多用户的情况下感觉不错,我的进程是root用户起的
[1]+  已终止               md5sum /dev/zero

如果需要在杀死进程前进行确认,可以使用killall的-i选项

[root@server ~]# md5sum /dev/zero &
[1] 13588
[root@server ~]# killall -i md5sum
杀死 md5sum(13588) ? (y/N) N
md5sum: no process found
[root@server ~]# killall -i md5sum
杀死 md5sum(13588) ? (y/N) Y
[1]+  已终止               md5sum /dev/zero

比较kill和killall命令,发现最大的不同就是一个接受进程号,一个接受进程名,其他不同不是很明显

pkill

help
Options:
 -<sig>, --signal <sig>    signal to send (either number or name)
 -e, --echo                display what is killed
 -c, --count               count of matching processes
 -f, --full                use full process name to match
 -g, --pgroup <PGID,...>   match listed process group IDs
 -G, --group <GID,...>     match real group IDs
 -n, --newest              select most recently started
 -o, --oldest              select least recently started
 -P, --parent <PPID,...>   match only child processes of the given parent
 -s, --session <SID,...>   match session IDs
 -t, --terminal <tty,...>  match by controlling terminal
 -u, --euid <ID,...>       match by effective IDs
 -U, --uid <ID,...>        match by real IDs
 -x, --exact               match exactly with the command name
 -F, --pidfile <file>      read PIDs from file
 -L, --logpidfile          fail if PID file is not locked
 --ns <PID>                match the processes that belong to the same
                           namespace as <pid>
 --nslist <ns,...>         list which namespaces will be considered for
                           the --ns option.
                           Available namespaces: ipc, mnt, net, pid, user, uts
 -h, --help     display this help and exit
 -V, --version  output version information and exit

For more details see pgrep(1).

pkill命令和kill命令类似,不过默认情况下pkill接受的是进程名,而非进程ID。并且pkill不支持信号名称。pkill提供了很多和kill相同的选项。例如:
$ pkill process_name
$ pkill-s SIGNAL process_name #SIGNAL是信号编号。

[root@server ~]# md5sum /dev/zero &
[2] 5078
[root@server ~]# pkill md5sum
[1]-  已终止               md5sum /dev/zero
[2]+  已终止               md5sum /dev/zero
[root@server ~]# md5sum /dev/zero &
[2] 7067
[root@server ~]# md5sum /dev/zero &
[3] 8599
[root@server ~]# pkill -o md5sum   #杀死较老的进程
[2]   已终止               md5sum /dev/zero
[root@server ~]# ps -ef |grep md5sum
root      8599 30354 99 22:43 pts/5    00:00:11 md5sum /dev/zero
root     13831 30354  0 22:43 pts/5    00:00:00 grep --color=always md5sum

pkill不支持信号名称。pkill提供了很多和kill相同的选项。
看到一篇不错的文章,专门介绍pkill的,如果想详细了解pkill还可以看看下面的博文
https://blog.csdn.net/carefree2005/article/details/118190076

简单介绍下找进程名称及PID方法
pgrep 进程名称 #显示进程ID
ps -ef |grep -i 进程名|grep -v grep #进程名称不用全称,不区分大小写

[root@server ~]# pgrep md5sum
8599
15282
[root@server ~]# ps -ef |grep -i mD5suM |grep -v grep
root      8599 30354 99 22:43 pts/5    00:16:27 md5sum /dev/zero
root     15282 30354 99 22:53 pts/5    00:06:51 md5sum /dev/zero
Logo

更多推荐