终止每个后台进程


10

我有一些Stopped后台流程。

kill $(jobs -p)而且kill `jobs -p`没有效果

kill %1kill %2等成功终止单个进程

如何使用一个命令杀死每个后台进程?

另外,为什么前两个命令对我不起作用?

我正在运行Linux Mint 15,64位

Answers:


10

当他们跑步时

似乎您可以使用kill和的输出来执行此操作jobs -p

$ sleep 1000 &
[1] 21952
$ sleep 1000 &
[2] 21956
$ sleep 1000 &
[3] 21960

现在我有3个伪造的作业正在运行。

$ jobs
[1]   Running                 sleep 1000 &
[2]-  Running                 sleep 1000 &
[3]+  Running                 sleep 1000 &

像这样杀死他们:

$ kill $(jobs -p)
[1]   Terminated              sleep 1000
[2]-  Terminated              sleep 1000
[3]+  Terminated              sleep 1000

确认他们都走了。

$ jobs
$

当他们停下来时

如果您有已停止的作业,但不运行,请执行此操作。

$ kill $(jobs -p)

$ jobs
[1]+  Stopped                 sleep 1000
[2]-  Stopped                 sleep 1000
[3]   Stopped                 sleep 1000

好的,这样不会杀死它们,但这是因为kill信号无法由进程本身处理,因此已停止。因此,请告诉操作系统执行杀死操作。那就是a的-9目的。

$ kill -9 $(jobs -p)
[1]+  Killed                  sleep 1000
[2]-  Killed                  sleep 1000
[3]   Killed                  sleep 1000

这样更好

$ jobs
$ 

当一些正在运行而一些已停止时

如果您有一些混在一起的流程,其中某些流程已停止且某些流程正在运行,则可以kill先执行,然后执行kill -9

$ kill $(jobs -p); sleep <time>; \
    kill -18 $(jobs -p); sleep <time>; kill -9 $(jobs -p)

如果需要更多时间以允许进程首先停止自身,则稍微延长时间。

讯号

杀死HUP(-1)或SIGTERM(-15)都不会成功。但为什么?这是因为这些信号在告诉应用程序终止自身的意义上是更好的。但是由于应用程序处于停止状态,因此无法处理这些信号。因此,您唯一的选择就是使用SIGKILL(-9)。

你可以看到所有这些信号kill与提供kill -l

$ kill -l | column -t
1)   SIGHUP       2)   SIGINT       3)   SIGQUIT      4)   SIGILL       5)   SIGTRAP
6)   SIGABRT      7)   SIGBUS       8)   SIGFPE       9)   SIGKILL      10)  SIGUSR1
11)  SIGSEGV      12)  SIGUSR2      13)  SIGPIPE      14)  SIGALRM      15)  SIGTERM
16)  SIGSTKFLT    17)  SIGCHLD      18)  SIGCONT      19)  SIGSTOP      20)  SIGTSTP
21)  SIGTTIN      22)  SIGTTOU      23)  SIGURG       24)  SIGXCPU      25)  SIGXFSZ
26)  SIGVTALRM    27)  SIGPROF      28)  SIGWINCH     29)  SIGIO        30)  SIGPWR
31)  SIGSYS       34)  SIGRTMIN     35)  SIGRTMIN+1   36)  SIGRTMIN+2   37)  SIGRTMIN+3
38)  SIGRTMIN+4   39)  SIGRTMIN+5   40)  SIGRTMIN+6   41)  SIGRTMIN+7   42)  SIGRTMIN+8
43)  SIGRTMIN+9   44)  SIGRTMIN+10  45)  SIGRTMIN+11  46)  SIGRTMIN+12  47)  SIGRTMIN+13
48)  SIGRTMIN+14  49)  SIGRTMIN+15  50)  SIGRTMAX-14  51)  SIGRTMAX-13  52)  SIGRTMAX-12
53)  SIGRTMAX-11  54)  SIGRTMAX-10  55)  SIGRTMAX-9   56)  SIGRTMAX-8   57)  SIGRTMAX-7
58)  SIGRTMAX-6   59)  SIGRTMAX-5   60)  SIGRTMAX-4   61)  SIGRTMAX-3   62)  SIGRTMAX-2
63)  SIGRTMAX-1   64)  SIGRTMAX

如果您想进一步了解各种信号,我强烈建议您阅读信号手册页man 7 signal


为什么+在第一个过程中有-符号,在第二个过程中有符号,而在第三个过程中没有符号?
Ramesh 2014年

我得到的结果和你一样。但是,我想terminate代替kill,因为我已经读过了,比较安全。我尝试过kill -15 $(jobs -p),但是没有效果。我猜想停止的进程只能被杀死,但是然后再次kill %number终止(单个)停止的进程。
user49888 2014年

@Ramesh +-是我设置示例时碰到的最后一个过程。这+意味着任何未明确包含a的%#命令都将对该命令起作用。破折号(-)是我触摸的倒数第二个命令。
slm

@ user49888- kill -9 .. 应该已经工作了。流程是什么?它们是已解散还是孤立的进程?
slm

1
@ user49888-是的,如果该进程处于某件事的中间,则在终止之前没有机会进行任何清理。
slm

2

你可以试试看

for x in `jobs -p`; do kill -9 $x; done

但是,如果要终止该过程,可以发出以下命令:

for x in `jobs -p`; do kill -15 $x; done

在命令的Wiki页面中Kill

可以通过四种方式向进程发送SIGTERM信号(在这种情况下,进程ID为'1234'):

kill 1234
kill -s TERM 1234
kill -TERM 1234
kill -15 1234

该过程可以发送一个SIGKILL三种方式信号:

kill -s KILL 1234
kill -KILL 1234
kill -9 1234

就像在这个答案中解释的,这是终止和之间的区别杀灭

终止信号SIGTERM是可以在程序中截获的信号。通常,打算在后台运行的进程会捕获此信号并启动关闭进程,从而导致干净退出。杀死信号终止 SIGKILL不能被截获。将其发送到进程时,将导致该程序的突然终止。

例如,当您关闭计算机或重新启动计算机时,通常会先将SIGTERM发送给正在运行的进程,如果允许的话,它们会以干净的方式退出。然后,几秒钟后,SIGKILL被发送到仍在运行的进程,以便强行释放正在使用的资源(例如正在使用的文件),并且关闭序列可以继续(例如卸载文件系统)。


这会执行kill每个后台进程。但是,terminate因为我认为这样比较安全,所以有什么办法可以代替他们吗?
user49888 2014年

如果要终止,可以-15在kill命令中使用。
Ramesh 2014年

-15也不会在这里工作。见我A.
SLM

@Ramesh-最后两段不正确。未发送SIGTERM(不是最初)。首先尝试通过服务停止/启动脚本停止进程。如果是这种情况,则将9发送到流程,然后按OP的示例中止进程,则kill -9在我的示例中将不起作用。
slm

1

好吧,我在处理这个问题时发现,当您杀死一个已停止的工作(执行已暂停但未终止)时,直到将其置于前台,该工作才结束。通常通过在终端上按Ctrl- Z来停止程序。SIGSTOP在这种情况下,大多数终端都会发送,但是当然还有其他发送方式,例如with kill -STOPkill -19

由于程序必须正在运行以处理SIGTERM发出的默认信号,因此通常不会立即结束程序kill。此外,有时在bash发送SIGTERM到后台进程后,它最终会以某种方式停止(尽管SIGTERM仍处于待处理状态)。

完成所有作业(求助于kill -9)的最安全方法是先SIGTERM使用normal kill发送,然后再发送SIGCONT至所有剩余的作业,例如:

kill $(jobs -p)
kill -18 $(jobs -p)

SIGCONT18是信号编号)会带来任何停止作业到前台,使他们能够处理SIGTERM,因为他们通常会。

如果不是所有程序都以此结束,那么您可以尝试使用其他一些信号,使该过程正常完成kill -9。我推荐的第一个SIGHUP程序是因为许多通常会阻止其他终止信号响应的程序SIGHUP。这通常在控制终端关闭时发送,特别是在ssh会话tty结束时发送。许多交互式程序(例如shell)不会响应其他终止信号,但会对此做出响应,因为在ssh会话结束后(或任何控制终端关闭之后),它们要保持运行状态是一个问题。要尝试这个,你可以这样

kill -1 $(jobs -p)
kill -18 $(jobs -p)

当然,再次需要确保程序没有停止,以便它可以处理信号。您可以尝试的其他终止信号是SIGINTkill -2)和SIGQUITkill -3)。但是,当然,尝试全范围的好处会减少,并可能导致不可避免的情况SIGKILL(aka kill -9)。


如果执行此操作man signal,则可以获取参考资料以进行备份。
slm

这是我的A建议的一种较柔和的形式。在过去的某些情况下,我仍然无法完全清除所有内容,因此,如果您通过脚本执行此操作,则该kill -9 ..方法在大多数情况下都可以使用。有时这会使进程徘徊,因此更多时候会失败。您必须决定权衡。最好使用笨拙的方式杀死所有内容,这要冒着数据/清理工作的风险,而要进行更轻松的清理,却要做更多的分析,因为您的杀死工作会越来越严厉。
slm

@slm,您应kill -9尽可能避免,因为这会拔掉插头而没有给程序适当的清理机会。我将更新一些替代方案。
Graeme 2014年

正如我说的那样,您的口味要比我建议的要柔和,这归结为您要尝试做的事情与愿意从风险角度忍受的事情。我和我一样都使用了您的方法。他们都是正确的海事组织。也是kill ..; sleep <time>; kill -18 ..; 睡眠<时间>; 杀死-9 ... . Basically working up to the -9`。
slm

@slm kill -18绝对是应该使用的东西,因为停止作业是很常见的(并且在某些情况下,似乎bash在发送之前以某种方式停止了运行作业SIGTERM)。上面添加的SIGHUP内容也值得尝试,因为许多不响应其他程序的程序将对此做出响应(使用shell进行尝试)。除此之外,是的,它并没有那么值得,因为SIGKILL它可能是不可避免的。
Graeme 2014年

0

这将一个接一个地终止当前shell中的所有作业:

while kill %; do :; done

说明:%引用列表中的最后一个作业,因此它将循环直到kill返回非零值,这意味着没有更多作业要终止。

另一种方法可能是先发送邮件SIGTERM,然后SIGCONT使您的工作继续进行,而他们要做的第一件事就是接收您的电子邮件SIGTERM

/bin/kill $(jobs -p) && /bin/kill -CONT $(jobs -p)

(由于某种原因,内置kill是奇怪的,所以我在这里使用了外部的)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.