如何使用kill、pkill和killall终止进程
1. 概述
Linux 提供了几个命令来结束或终止进程 。尽管它们使用的底层系统调用相似,但每个都有自己的优势。
在这个简短的教程中,我们将看到每个命令的好处,以及每个命令的优势示例。
2. 什么是kill系统调用?
在 Linux 上,系统调用是访问内核功能的接口。可以通过要求内核为我们完成低级任务来执行它们。 要结束进程,我们可以使用kill 系统调用。它有两个参数:进程 ID 和 终止进程时要发送的信号 。
信号指示终止进程的原因 。它由名称和相关编号组成。**该过程将根据其接收到的信号做出不同的响应。**我们可以向正在终止的进程发送许多信号,但让我们看看最常用的几个。
我们可以发送信号SIGTERM (15)或SIGINT (2) 来要求进程正常关闭。该进程可以忽略此请求。
我们可以发送SIGKILL (9) 或SIGSTOP ( 19),这是不能忽略的。SIGKILL强制进程终止,而SIGSTOP暂停它。
在本教程中,我们将专注于终止进程,但多亏了信号,我们可以更广泛地使用kill调用。例如,我们可以暂停和恢复进程,或者让它们重新加载它们的配置。
现在让我们看看命令如何使用这个系统调用。
3. kill
kill 命令是**系统调用最简单的包装器。**它需要进程 ID,并且默认情况下会向进程发送SIGTERM信号。要使用它,我们需要先使用ps 命令找到进程 ID :
$ ps x
PID TTY STAT TIME COMMAND
...
15709 pts/0 Ss 0:00 bash
16299 ? Sl 0:00 /usr/bin/gedit --gapplication-service
16405 pts/0 R+ 0:00 ps x
假设我们要终止gedit。我们可以执行以下命令:
$ kill 16299
如果我们想确定它已终止,我们可以传入SIGKILL:
$ kill -9 16299
# Or by signal name kill -SIGKILL 16299
kill命令很简单。我们只需要找到PID就可以使用了。这是一个优势,因为如果 PID 不存在,该命令将返回错误。
4. pkill
在大多数情况下,当我们想要终止一个进程时,我们也知道它的名字。这就是pkill 如此有用的原因。我们现在可以使用它的名称来终止gedit进程:
$ pkill gedit
此命令将模式作为唯一必需的参数。该模式将与所有进程名称匹配,匹配的进程将被终止。这也是一把双刃剑,因为我们可以终止我们无意终止的进程。
最好首先检查与模式匹配的进程。我们可以为此使用pgrep :
$ pgrep -a gedit
16299 /usr/bin/gedit --gapplication-service
现在我们可以放心地使用pkill了。
与kill命令一样,要发送的默认信号是SIGTERM。我们可以强制终止:
$ pkill -9 gedit
我们还可以用pkill做一些其他有趣的事情。例如,我们可以将搜索限制为属于特定用户的进程:
$ pkill -u myuser,otheruser gedit
或者杀死除匹配进程之外的所有进程:
$ pkill -u myuser --inverse gedit
5. killall
最后,killall 是另一个有用的命令。默认情况下,它只会终止与名称参数完全匹配的进程。例如,此命令不会找到任何进程:
$ killall gedi
但是如果我们使用pkill ,同样的论点也会起作用。如果我们知道进程的名称并希望避免杀死我们无意中匹配的进程,这绝对是一个优势。
与其他命令一样,该命令也接受信号作为参数,例如*-SIGKILL或-9*。与kill类似,如果没有进程与参数匹配,此命令将返回错误。
与pkill命令一样,我们也可以终止单个用户的所有进程:
$ killall -u otheruser
两个特性使killall独一无二。首先,我们可以交互式地执行它以确认我们找到了正确的进程:
$ killall -i gedit
Kill gedit(16299) ? (y/N)
其次,我们可以根据进程开始的时间来终止它。例如,要终止一小时前或之前启动的所有gedit进程,我们可以运行:
$ killall -i --older-than 60m gedit
Kill gedit(16299) ? (y/N)
或者我们可以终止最近 2 小时内启动的所有gedit进程:
$ killall -i --younger-than 2h gedit
Kill gedit(16299) ? (y/N)