通过管道杀死所有挂起的进程

通过管道杀死所有挂起的进程

我正在运行一个脚本,在杀死之前必须暂停该脚本。我第一次运行它时,该进程只有一个 pid。我杀死它并再次运行,PID 的数量不断增加。首先,为什么会有这种行为?如何在不明确提及每个 PID 的情况下杀死所有挂起的进程?

./toplog.sh

暂停:

Ctrl-Z

列出挂起的进程:

jobs -l

输出:

[1]  12055 Stopped                 ./toplog.sh
[2]  12752 Stopped                 ./toplog.sh
[3]- 13276 Stopped                 ./toplog.sh
[4]+ 13579 Stopped                 ./toplog.sh

杀戮:

kill 12055 12752 13276 13579

答案1

我正在运行一个脚本,在杀死之前必须暂停该脚本。

呃,不。脚本在终止之前不需要暂停。你可以随时杀死它。

我第一次运行它时,该进程只有一个 pid。我杀死它并再次运行,PID 的数量不断增加。

那么你实际上并没有杀死它!如果运行./toplog.sh并挂起它,则只会创建一个作业,即 的输出中的一行jobs。脚本本身可能会创建多个进程,但jobs仅列出脚本本身(技术术语为进程组领导者)。如果您看到越来越多的工作,这意味着您仍然看到您试图取消但未成功的旧工作。

你未能杀死这些工作的原因可能是因为它们被暂停了。当进程被挂起时,它无法对信号做出反应。如果向挂起的进程发送信号,则该信号仅在进程恢复时才有效。异常是由内核直接管理的信号,不涉及进程。其中一个例外是恢复进程的信号 (SIGCONT) 显然会立即唤醒进程。另一类异常是在不询问的情况下终止进程的信号:这始终包括 SIGKILL,如果进程尚未为​​该信号设置处理程序,还包括其他信号(SIGINT、SIGHUP、SIGTERM、SIGQUIT...)。

如果kill %1终止作业 1,那么 shell 会告诉您该作业已终止。如果进程设置了 SIGTERM 处理程序,则kill %1在进程挂起时无效;要终止该进程,您还需要恢复它:

kill %1; kill -CONT %1

如果您想强制终止该进程而不给它任何清理机会,那么请执行以下操作

kill -KILL %1

(或kill -9 %1简称)。

如果您想终止所有toplog.sh进程,无论它们是否从该终端启动,您可以使用pkill toplog.sh.

答案2

当您知道运行时如何调用进程时(在本例中是toplog.sh),您可以终止脚本的所有实例。

ps x | grep toplog.sh | grep -v grep | cut -d" " -f1 | xargs kill -9

ps x为您提供所有进程的列表,将从目标进程中进行 grep。第二个 grep 只是确保从列表中删除 grep 调用本身。否则你会得到一个错误(事实上这仍然没问题,但很难看)。切 -d" " -f1将每一行分成多个部分,并用空格字符划分,其中 *-f1** 占据第一部分。xargs杀-9杀死之前从命令链中抛出的每个 pid。

为了方便起见,您可以将此行放入终止脚本中,其中进程名称将替换为终止脚本参数:

#!/bin/bash
ps x | grep $1 | grep -v grep | cut -d" " -f1 | xargs kill -9

然后使用要终止的进程的名称调用该脚本。

./kill.sh toplog.sh

相关内容