linux:杀死后台任务


194

如何杀死linux中最后一个生成的后台任务?

例:

doSomething
doAnotherThing
doB &
doC
doD
#kill doB
????

18
这怎么可能与编程无关?Bash编程不编程吗?
flybywire

6
这是在SO和SU之间的重叠区域中,但我认为它更适合SO。我以这种方式思考的标准是,如果@flybywire在脚本中执行此操作,则表示正在编程。如果他只是想从命令行执行此操作,我会说它属于SU。
比尔蜥蜴,

10
Shell脚本也在编程中。
cletus

Answers:


234

bash中有一个特殊的变量:

kill $!

$!扩展为在后台执行的最后一个进程的PID。


68
@ polm23; 不,^Z不是后台作业,它会阻止它们。随后的对象bg执行实际的“后台”(在后台继续执行),然后$!按预期工作。
falstro 2012年

假设????终止后要执行一个或多个命令,如果这些命令中的任何一个依赖于后台进程完成的工作,请注意后台进程在执行完信号处理程序后可能执行的任何清理或整理任务接收(可陷阱)信号。最好在任何此类“相关”命令的第一个之前添加一个wait(可能紧接着一个sync,甚至一个sleep <n>)。
确认

2
完成:由于单个%也指当前作业,因此您可以使用“ kill%”杀死已停止的作业(^ z)。我几乎总是在^ z之后使用它。
t3o

这仅在启用了作业控制的情况下才有效,默认情况下,它仅在交互式外壳程序中处于启用状态(尽管由于您指的是使用ctrl-z,所以我猜您也指的是使用交互式外壳程序)-但这已经在此处的其他答案中概述了这些信息,但不确定为什么是“出于完整性” :)
falstro

289

您可以按职位编号杀死。将任务放在后台时,您会看到类似以下内容的内容:

$ ./script &
[1] 35341

[1]是工作编号,可以像这样引用:

$ kill %1
$ kill %%  # Most recent background job

要查看作业编号列表,请使用jobs命令。更多来自man bash

在Shell中有多种方法可以引用作业。角色%介绍了工作名称。作业编号n可以称为%n。也可以使用用于启动作业的名称前缀或使用其命令行中出现的子字符串来引用作业。例如,%ce是指已停止的ce作业。如果前缀与多个作业匹配,则bash报告错误。%?ce另一方面,using表示ce在命令行中包含字符串的任何作业。如果子字符串匹配多个作业,则bash报告错误。符号%%%+引用当前作业的外壳程序概念,即在作业在前台或在后台启动时停止的最后一个作业。可以使用引用以前的作业%-。在与作业有关的输出中(例如,作业命令的输出),当前作业始终用标记+,而先前作业则用标记-。单个%(无随附的工作说明)也指当前工作。


作为记录,我认为这仅在启用作业控制的情况下有效。尽管我认为您可以在脚本(set -m)中将其打开,但它仅供交互使用。见stackoverflow.com/questions/690266/...以及
falstro

9
非常有用的符号,这些%1%%-特别。有些事情不会在Ctrl-C上消失,因此您需要先按Ctrl-Z,然后再按kill -9 %%。我发现它有用的一个示例是:while true; do mplayer <some unstable online radio>; date >> restarts.log; done-Ctrl-C只会使您进入下一个循环迭代。在我不得不做ps或也许做之前jobs -l,然后重新输入PID,这很繁琐。
Tomasz Gandor 2014年

是否有一份适合所有工作?
CMCDragonkai 2014年

3
@TomaszGandor这就是为什么您可能想要替换while true为的原因while sleep 1。如果可以忍受,这将给您带来短暂的延迟,然后重新启动,并且如果您按两次ctrl-c,第二次将中断睡眠,并以非零退出结束睡眠并退出循环。
falstro,2014年

45

以下命令为您提供了会话中所有后台进程的列表以及pid。然后,您可以使用它来终止进程。

jobs -l

用法示例:

$ sleep 300 &
$ jobs -l
[1]+ 31139 Running                 sleep 300 &
$ kill 31139


2
skill doB

skill 是kill命令的一个版本,可让您根据给定的条件选择一个或多个进程。



0

这是一个脱口而出的答案,但是,对于那些有兴趣的人来说,这可能是有价值的。

就像@John Kugelman的答案一样,%与工作规范有关。 如何有效地找到那个?使用less的&pattern命令,似乎man使用的寻呼机较少(不确定),在man bash中键入&%然后键入Enter将只显示包含'%'的行,以全部显示,键入&。然后输入。


-3

只需使用killall命令:

killall任务名称

有关更多信息和更多高级选项,请键入“ man killall”。


4
我认为当您实际上可以轻松访问PID时,killall有点激进。而且也很危险,尤其是如果您是root
Dave Vogt

3
如果必须使用killall pythonkillall java,而在系统中的其他地方运行有用的东西时,它不是很有帮助。
Tomasz Gandor 2014年
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.