在面试的时候被问道了这个问题,之前还从来没有了解过

1.怎么终止某个进程?

如果你学过Linux下的信号处理,这个问题应该不难答。在Linux下,使用kill命令发送信号给进程,其中9号信号SIGKILL就可以将进程终止。

还有很多其他信号也能终止进程,比如前台进程使用CTRL+C会发送2号信号,也能终止进程。但是9号信号是不能被自定义捕获的,进程收到9号信号后一定会被终止。

后台进程就需要我们知道这个进程的名字,然后查询这个进程的PID,再用kill发送信号将其终止。在之前我都是用下面这两个命令来处理的

1
2
ps jax | grep 进程名 | grep -v grep
kill -9 进程PID

现在的问题就变成了,如何将这两条命令变成一条命令?

2.如何用一条命令终止后台进程?

2.1 pkill/killall

在Linux下除了kill命令,还有这两个命令,他们可以通过传入进程名字来删除某个进程

1
2
pkill 进程名
killall 进程名

如下所示,我用c语言写了个死循环的程序,并让其后台运行。

1
2
❯ ./test &
[1] 2578

随后,可以使用pkill命令直接终止这个程序

1
2
3
4
❯ 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命令也是同理,需要注意的是,如果有两个同名的进程,这两个进程都会被终止。

1
2
3
❯ killall test
[1] - 7309 terminated ./test
[2] + 7327 terminated ./test

pkill和killall的区别在于,pkill是用正则捕获的方式来查询某个进程的,即输入test,实际上会删除所有进程名中包含test的进程。而killall则是完全捕获,必须是名字为test的进程才会被删除。

如下所示,使用pkill est命令,同样会删除test进程。

1
2
❯ pkill est                        
[1] + 7664 terminated ./test

而killall则不会,会显示该进程名找不到对应进程。

1
2
❯ killall est 
est: no process found

另外,pkill命令可以传入用户参数,只干掉某个用户下的某个进程

1
pkill 用户名 进程名

2.2 ps+kill+管道

因为没有接触过上面的pkill命令,所以我当时面试的时候只能想到通过管道的方式来查询进程PID并将其传给kill命令。不过因为对linux下命令行的管道了解的并不多,具体怎么写命令也说不出来。

我们知道,使用ps命令的时候,显示的数据中第二列是该进程的PID,第一列是父进程的PID。即我们需要想办法把这个结果中第二列的值给取出来。

1
2
❯ ps jax | grep test | grep -v grep                          
2265 9356 9356 2265 pts/5 9450 SN 1000 0:00 ./test

使用awk命令就能做到这一点,从匹配的行中取出第二列,即得到了我们需要的进程PID。

1
2
❯ ps jax | grep test | grep -v grep | awk '{print $2}'
9356

现在要做的就是用$号将这个命令的结果传给kill命令,这样就实现了用一条命令终止进程了。

1
2
❯ kill -9 $(ps jax | grep test | grep -v grep | awk '{print $2}')
[1] + 9356 killed ./test

The end

有其他办法,欢迎在评论区交流!