共计 3939 个字符,预计需要花费 10 分钟才能阅读完成。
如何优雅的杀掉一个过程
前言
在咱们通常应用 linux 操作系统的时候,常常会有这样的需要——杀死一个过程,比如说你一不小心启动了一个后盾过程或者守护过程,而这个过程是你不须要的,因而你久想杀掉他,在本篇文章当中次要给大家介绍一些杀死过程的办法,以及这暗藏在这前面的原理。
你能够杀死哪些过程
在咱们杀死一个过程的时候最好不要应用管理员权限,因为你可能会一不小心杀死零碎当中一些很重要的过程。同时须要理解,在 linux 当中有很多与权限相干的操作,如果你只是一个一般的用户,那么你就只能杀死你本人的过程,不可能杀死别的用户的过程。然而 root 用户或者你有 sudo 权限,那么你就能够随心所欲了😂。
杀死过程的基本原理:咱们应用命令去杀死过程,实质上是通过一个过程(比如说 kill 命令的那个过程)给另外一个过程发送信号,当过程接管到信号的时候就会进行判断是哪个信号,而后依据不同的信号做出相应的行为。
信号后面示意代表不同信号的数值,比如说咱们执行命令 kill -9 1234
就是将 9 这个值对应的信号 SIGKILL 发送给过程号等于 1234 的过程,在 linux 操作系统当中,常见的信号如下所示:
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
对于信号来说,过程能够有不同的应答行为,具体来说次要有以下三种:
- 疏忽这个信号。
- 应用默认行为去解决这个信号,比方 SIGINT 和 SIGTERM 这两个信号的默认行为就是退出程序。
- 本人定义函数捕捉这个信号,咱们能够本人写一个函数,并且应用零碎调用将这个函数进行注册,当收到对应的信号的时候就去执行咱们本人实现的函数,然而须要留神的是,并不是所有的信号咱们都能够进行捕捉的,比如说 SIGKILL 和 SIGSTOP 这两个信号。
程序的定位
咱们通常能够应用 ps 和 top 两个命令进行程序的定位,在后面的两篇文章 Linux 命令系列之 top——外面藏着很多鲜为人知的宝藏常识和这才是应用 ps 命令的正确姿态当中我么曾经认真探讨过这个问题了!因而当咱们想要杀死某个程序的时候咱们能够通过上述两个命令进行程序的定位,找到咱们想要杀死的过程的过程号和过程名字。
在本篇文章当中次要应用一个程序 group.c 作为例子,讲述各种 kill 命令的应用,他会 fork 出几个子过程,子过程的过程名和它的过程名都是 group.out,这个程序的源代码如下所示:
#include <stdio.h>
#include <unistd.h>
int main() {for(int i = 0; i < 10; i++) {if(!fork())
break;
}
printf("过程 ID = %d 过程组 ID = %d\n", getpid(), getpgid(0));
sleep(100);
return 0;
}
应用 kill 命令杀死过程
kill 命令的应用办法如下所示:
kill [option] <pid> [...] # [option] 是参数选项比方 -9 pid 示意过程的过程 id
发送一个 SIGINT 信号给过程 1234
kill -SIGINT 1234
或者
kill -2 1234
如果过程 1234 执行 SIGINT 的默认行为的话,那么过程 1234 就会退出,因为默认行为就是退出程序。
强制杀死过程 1234
kill -SIGKILL 1234
或者
kill -9 1234
因为信号 SIGKILL 是不可能被疏忽或者捕捉的,这个就是强制杀死程序,这条命令能够保障肯定杀死过程,然而咱们个别状况下最好不要应用这条命令,因为很多程序有他本人的逻辑,比方清理一些数据和系统资源,然而如果你不关怀这些就无所谓了。
杀死所有你有权限杀死的过程
kill -9 -1
下面的命令当中 -1 的意思示意将 -9 这个信号发送给所有你有权限发送的过程,这个命令慎用。
有的时候咱们会有一个需要就是杀死一个过程组外面的所有过程,咱们能够应用命令
kill [option] -<pid> [...] # [option] 是参数选项比方 -9 pid 示意过程的过程 id
就是在 pid 后面加上 - 示意杀死这个过程组,比方上面图中的示例:
在 kill 命令当中如果没有指定发送那个信号的话,默认就发送 SIGTERM 信号,对应的数值等于 15。
pkill 和 pgrep
pgrep 命令其实就是依据正则表达式列出相应的过程。默认他只会讲符合要求的过程的过程号列出来:
➜ pthreads pgrep out
3204266
3204268
3204269
3204270
3204271
3204272
3204273
比如说,列出所有含有 out 这个字符的过程:
➜ pthreads pgrep -l out
3204266 group.out
3204268 group.out
3204269 group.out
3204270 group.out
3204271 group.out
3204272 group.out
3204273 group.out
pgrep -l out
在下面的命令当中 out 示意一个字符串,咱们也能够应用正则表达式,-l 示意列出过程执行的时候的命令。
在 pgrep 当中还有一个比拟重要的选项 -u,这个选项示意依据特定的用户筛选过程,比如说咱们只有 abc 这个用户的过程,能够这样:
pgrep -u abc out # 也是抉择含有 out 字符串的过程
pgrep 还有一个比拟重要的选项就是 -v,这个选项的意思就是除了合乎正则表达式要求的其余过程,比如说咱们想要将所有不含 out 的过程筛选进去,就能够应用如下命令:
pgrep -v out
如果咱们想要统计一下符合要求的过程的个数咱们能够应用上面的这个命令:
pgrep -c out # 统计一下含有 out 字符串的过程的个数
pkill 的应用形式和 pgrep 是一样的只不过 pgrep 是将过程的过程号列出来,而 pkill 是将一个发送给所有符合要求的过程,默认发送的信号是 SIGTERM 对应的值等于 15。
比方在上图当中就发送一个默认信号 SIGTERM 给所有命令行当中还有字符串 out 的过程。因而 pkill 在批处理场景用的比拟多,将还有某个特色的过程全副杀死。
如果你想指定具体发送那个信号格局和 kill 是一样的,比方发送 SIGKILL(-9)信号给含有字符串 out 的过程。
pkill -9 out
或者
pkill -SIGKILL out
应用 killall 命令
Killall 和 pkill 应用办法差不多,而且含意也统一,将符合条件的过程全副杀死。默认发送的信号也是 SIGTERM,信号值等于 15,然而 pkill 不同的是 killall 默认不开启正则表达式,咱们须要通过 -r 选项启动正则表达式辨认。
例子如下所示:
如果咱们想在不实用 -r 选项的状况下杀死过程,只能输出过程的全称了。
在 killall 命令当中还有一些罕用的选项:
选项 | 含意 |
---|---|
-u | 只杀死指定用户的过程,比如说 -u abc 只杀死用户 abc 满足要求的过程 |
-I | 字母大小写不敏感 |
-i | 交互模式,每次杀死过程都会询问是否杀死过程 |
-r | 示意应用正则表达式进行匹配 |
- 数字或者信号名 | 发送特定的信号,如下的例子所示 |
为什么咱们不可能捕捉所有的信号
在后面的文章当中咱们提到了,SIGKILL 和 SIGSTOP 这两个信号是不可能被捕捉的!试想一下,在你的零碎的当中有一个病毒程序,他会一直的创立新的过程并且一直的申请系统资源,那么你还没有方法杀死他,你只可能眼睁睁的看着你的零碎卡死。这种问题 linux 设计者早就想到了,基于这个问题就必定须要有一种形式可能十拿九稳的杀掉过程,因为咱们不可能让一个过程无休止的耗费系统资源而咱们却无能为力,因而才呈现了不可能被捕捉的信号,因为这个可能确保杀死过程。
总结
在本篇文章当中次要给大家介绍各种 kill 命令的应用办法以及一些简略的信号含意的介绍,这部分内容在咱们平时的学习工作过程当中常常会应用到,心愿大家有所播种~
以上就是本篇文章的所有内容了,我是 LeHung,咱们下期再见!!!更多精彩内容合集可拜访我的项目:https://github.com/Chang-LeHu…
关注公众号: 一无是处的钻研僧 ,理解更多计算机(Java、Python、计算机系统根底、算法与数据结构)常识。