Linux 命令行提供了各种命令来终止进程。例如,“kill”命令可用于通过将其 PID 作为参数传递来杀死进程,“pkill”命令将模式作为输入并杀死所有匹配的正在运行的进程。但是有一个命令'killall',它默认与参数名称完全匹配,并终止匹配过程。
在本文中,我们将通过一些实际示例来讨论这个命令。killall 命令可用于通过使用其名称向特定进程发送信号。这意味着如果您运行同一程序的五个版本,killall 命令将杀死所有五个版本。
该信号可以指定为此命令的参数,否则默认发送SIGTERM 。一个进程可以生成独立于父进程的子进程,这意味着每个子进程都通过它的pid来标识。使用 kill 命令,我们使用 pid 选择要杀死的子进程,但是使用 killall 命令,通过指明名称,因为所有子进程和进程父进程名称相同,所有进程都会被杀死。
让我们通过一些实际的例子来讨论 killall 命令的用法。
1) 列出所有支持的信号
Kill 命令支持一些可以用-l
选项列出的信号。killall 向进程发送信号。您可以使用该-s
选项(后跟信号名称)将特定信号发送到进程。
$ killall -l
HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM
STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS
UNUSED
默认情况下SIGTERM/TERM (15)被发送到进程,如果没有信号则给 killall 命令。用户和系统管理员都可以使用上述信号。所以 killall 支持所有这些信号。
2)杀死一个特定的进程
要杀死一个进程,我们需要识别它以检查它是否正在运行。我们可以通过它的名字杀死一个特定的进程。假设,有两个具有相同初始字符的进程:
iPhone 13 / Pro / Max:提示和技巧
$ ps -aef | grep "test"
himanshu 3969 2811 0 14:14 pts/0 00:00:00 ./test
himanshu 3970 2811 0 14:14 pts/0 00:00:00 ./test_again
现在,您可以使用 killall 命令杀死 'test_again' :
$ killall test_again
[2]+ Terminated ./test_again
如您所见,killall 命令终止了“test_again”进程。这也可以通过 ps 命令确认:
$ ps -aef | grep "test"
himanshu 3969 2811 0 14:14 pts/0 00:00:00 ./test
观察到 'test_again' 没有显示在输出中,因为它被杀死了。
3)杀死一个进程忽略大小写
killall 命令默认区分大小写。这是一个例子:
$ ps -aef | grep "test"
himanshu 4177 3161 0 14:54 pts/3 00:00:00 ./test
himanshu 4178 3161 0 14:54 pts/3 00:00:00 ./test_again
himanshu 4180 3161 0 14:54 pts/3 00:00:00 grep --color=auto test
你可以看到我们所有的进程都是小写的。让我们尝试杀死“./test”进程,但我们以大写字母输入名称
$ killall TEST
TEST: no process found
所以你可以看到 killall 命令找不到任何名为 TEST 的进程,而名为 'test' 的进程已经在运行。要确保 killall 命令忽略大小写,请使用该-I
选项。这是一个例子:
$ killall -I TEST
[1]- Terminated ./test
请注意,现在它成功终止了“测试”过程。
4) 确认终止进程
killall 命令可用于杀死多个进程。
$ killall test test_again
[2]- Terminated ./test_again
[3]+ Terminated ./test
但是,通过指示另一个名称插入进程名称时可能会发生错误。如果指示的进程是系统的关键进程,则可能是一个严重的问题。因此建议使用 killall 通过请求确认以交互方式终止进程。为此,您可以使用该-i
选项。
$ killall -i test test_again
Kill test(4201) ? (y/N) y
Kill test_again(4202) ? (y/N) y
[1]- Terminated ./test
[2]+ Terminated ./test_again
所以你可以看到这种方式用户可以使用 killall 命令控制进程的终止。
5)安静地杀死进程
有时当 killall 无法找到指定的进程时,它会在输出中抱怨相同的内容。
这是一个例子:
$ killall TEST
TEST: no process found
但是,如果您希望 killall 安静地执行其工作,您可以使用以下-q
选项:
$ killall -q TEST
$
所以你可以看到,当使用 -q 时,输出被抑制了。
6) killall 命令的奇怪结果
killall 命令的手册页说,默认情况下,它仅匹配长度小于或等于 15 个字符的完整名称。因此,如果命令名称超过 15 个字符,则完整名称可能不可用(即被换出)。在这种情况下,killall将杀死前 15 个字符内匹配的所有内容。
例如,假设有以下两个具有长名称的进程:
$ ps -aef | grep "test"
himanshu 4021 3161 0 14:27 pts/3 00:00:00 ./test_abcdefghij
himanshu 4035 3161 0 14:27 pts/3 00:00:00 ./test_abcdefgh
上面输出中的第一个进程的名称正好有 15 个字符。让我们尝试使用 killall 命令杀死它:
$ killall test_abcdefghij
[1]- Terminated ./test_abcdefghij
所以可以看到killall命令成功杀死了进程。
现在,根据手册页,如果两个名称的匹配字符超过 15 个,killall 将终止名称后跟-e
选项的进程,否则它将终止前 15 个字符内匹配的所有内容。这是一个例子:
$ ps -aef | grep "test"
himanshu 4114 3161 0 14:40 pts/3 00:00:00 ./test_abcdefghijklmnopqrstuvwx
himanshu 4141 3161 0 14:46 pts/3 00:00:00 ./test_abcdefghijklmnopqrstuvwxyz
himanshu 4143 3161 0 14:46 pts/3 00:00:00 grep --color=auto test
请注意,这两个进程的名称中现在都有超过 15 个匹配字符。现在,当我尝试使用 killall 杀死第二个进程时:
$ killall test_abcdefghijklmnopqrstuvwxyz
[6]+ Terminated ./test_abcdefghijklmnopqrstuvwxyz
它只杀死了指定的进程,而不是第二个进程
$ ps -aef | grep "test"
himanshu 4114 3161 0 14:40 pts/3 00:00:00 ./test_abcdefghijklmnopqrstuvwx
himanshu 4146 3161 0 14:47 pts/3 00:00:00 grep --color=auto test
我不确定我这边是否有错误,或者是 killall 命令中的错误。如果您在评论中提出您对此的看法,我将不胜感激。
顺便说一句,这里是我系统上 killall 命令的详细信息:
$ killall --version
killall (PSmisc) 22.20
Copyright (C) 1993-2012 Werner Almesberger and Craig Small
PSmisc comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it under
the terms of the GNU General Public License.
For more information about these matters, see the files named COPYING.
结论
从 Centos 7 开始,它鼓励运行 pkill 而不是 killall,因此默认情况下,当您运行命令时,您可能会收到“killall: command not found”错误。如果您仍然需要它,请通过添加 psmisc 包来安装 pkill (# yum install psmisc)。