在面试的时候被问道了这个问题,之前还从来没有了解过
1.怎么终止某个进程?
如果你学过Linux下的信号处理,这个问题应该不难答。在Linux下,使用kill命令发送信号给进程,其中9号信号SIGKILL
就可以将进程终止。
还有很多其他信号也能终止进程,比如前台进程使用CTRL+C
会发送2号信号,也能终止进程。但是9号信号是不能被自定义捕获的,进程收到9号信号后一定会被终止。
后台进程就需要我们知道这个进程的名字,然后查询这个进程的PID,再用kill发送信号将其终止。在之前我都是用下面这两个命令来处理的
ps jax | grep 进程名 | grep -v grep
kill -9 进程PID
现在的问题就变成了,如何将这两条命令变成一条命令?
2.如何用一条命令终止后台进程?
2.1 pkill/killall
在Linux下除了kill命令,还有这两个命令,他们可以通过传入进程名字来删除某个进程
pkill 进程名
killall 进程名
如下所示,我用c语言写了个死循环的程序,并让其后台运行。
❯ ./test &
[1] 2578
随后,可以使用pkill命令直接终止这个程序
❯ ps jax | grep test | grep -v grep
2265 2578 2578 2265 pts/5 3337 SN 1000 0:00 ./test
❯ pkill test
[1] + 2578 terminated ./test
killall命令也是同理,需要注意的是,如果有两个同名的进程,这两个进程都会被终止。
❯ killall test
[1] - 7309 terminated ./test
[2] + 7327 terminated ./test
pkill和killall的区别在于,pkill是用正则捕获的方式来查询某个进程的,即输入test,实际上会删除所有进程名中包含test的进程。而killall则是完全捕获,必须是名字为test的进程才会被删除。
如下所示,使用pkill est
命令,同样会删除test进程。
❯ pkill est
[1] + 7664 terminated ./test
而killall则不会,会显示该进程名找不到对应进程。
❯ killall est
est: no process found
2.2 ps+kill+管道
因为没有接触过上面的pkill命令,所以我当时面试的时候只能想到通过管道的方式来查询进程PID并将其传给kill命令。不过因为对linux下命令行的管道了解的并不多,具体怎么写命令也说不出来。
我们知道,使用ps命令的时候,显示的数据中第二列是该进程的PID,第一列是父进程的PID。即我们需要想办法把这个结果中第二列的值给取出来。
❯ ps jax | grep test | grep -v grep
2265 9356 9356 2265 pts/5 9450 SN 1000 0:00 ./test
使用awk命令就能做到这一点,从匹配的行中取出第二列,即得到了我们需要的进程PID。
❯ ps jax | grep test | grep -v grep | awk '{print $2}'
9356
现在要做的就是用$
号将这个命令的结果传给kill命令,这样就实现了用一条命令终止进程了。
❯ kill -9 $(ps jax | grep test | grep -v grep | awk '{print $2}')
[1] + 9356 killed ./test
The end
有其他办法,欢迎在评论区交流!