我正在运行一个脚本,在杀死之前必须暂停该脚本。我第一次运行它时,该进程只有一个 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