如何杀死所有停止的工作?


91

当我尝试从Linux服务器退出时,出现以下消息:

有停止的工作。

:是否有单个命令可以杀死这些?


U&L问答中的其他示例:unix.stackexchange.com/questions/124428/…–
slm

我现在遇到了相反的问题,当我退出shell时,它不会警告已停止的工作!必须shopt -s checkjobs输入我的.bashrc
Sam Watkins

1
再次按ctrl + d,它将使您现在退出,从而杀死了这些工作
Jens Timmerman

Answers:


73

要快速杀死所有在bash下停止的作业,请输入:

kill -9 `jobs -ps`

jobs -ps列出已-p停止(-s)作业的进程ID()。
kill -9 `jobs -ps`将SIGKILL信号发送给所有人。


22
-1表示“杀死工作”

1
工作是“ sudo su”时没有工作。即sudo kill `jobs -p`没有工作,但显式输入PID是。
user13107 2012年

14
为什么这么高的评价?这是不对的。如果进程已停止,则kill诸如此类的操作将无效,因为进程已停止,所以它们将不处理默认情况下发送给他们的SIGTERM(-15)。
slm 2014年

6
杀死-9将达到目的。
timetofly 2014年

84

尝试输入以下内容:

kill -9 $(jobs -p)

9
应该可以,但是我认为他应该先发送SIGTERM(-15),然后再发送SIGKILL(-9)。因此,也许建议像“杀死$(jobs -p);睡眠3s;杀死-9 $(jobs -p)”之类的东西会更好。首先发送SIGTERM作业可能能够执行干净的退出操作(释放分配的资源等)。
rems 2011年

3
凯文·杜克,您的答案就是对我有用的答案。我无法投票,因为我没有15个声誉。杀了-9 $(jobs -p)

2
@rems除了slm所指出的那样,它们不会得到SIGTERM,因为它们已停止。
Paul Gear

1
在zsh上不起作用。由于zsh不能 与Job兼容POS IX
Max Coplan

那么,如何处理zsh?
fx-kirin

16

接受的答案将杀死所有作业(在这种情况下足够),而不仅仅是终止的作业。如果您只想杀死已停止的那些,请运行:

kill $(jobs -l | grep Stopped | cut -d' ' -f3)

grep / cut可以在一个awk命令中组合: awk '/Stopped/{print $3}')
laebshade 2015年

2
-s接受的答案的参数仅过滤已停止的答案
79E09796 '17

12

最简单的方法实际上是立即重试退出。bash将其表示为“杀死所有停止的工作并退出”。


4
这将发送一个HUP,它不一定会停止任何作业。
Stephen Niedzielski 2014年

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

2
您可以为此行添加代码格式,以使其更易于阅读。
drcelus

您能否再次查看格式-在行的开头使用四个空格将一个块标记为代码(而不是使用反引号)。现在尚不清楚您是在代码中使用反引号,还是尝试使用反引号显示代码。
dunxd

格式很好。我们必须使用反引号传递作业-p,否则它将不会被视为命令,并且将引发错误。
2013年

5

以防万一这对其他人有帮助-大多数人在这里是因为他们启动了一些已停止的进程,也许是通过Shell作为后台的。我需要找到被其他用户停止的根用户进程,而该jobs命令的变体将无法执行。

进行一些挖掘使man ps我明白了这一点:

ps -a -o pid,user,cmd,state | grep 'T$'

说明:该-a标志表示显示所有进程,然后-o控制输出,将显示有关每个进程的信息。我选择的pidusercmd(命令行)和state,这是进程状态

来自man ps

PROCESS STATE CODES
   Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the
   state of a process:
           D    uninterruptible sleep (usually IO)
           R    running or runnable (on run queue)
           S    interruptible sleep (waiting for an event to complete)
           T    stopped, either by a job control signal or because it is being traced
           W    paging (not valid since the 2.6.xx kernel)
           X    dead (should never be seen)
           Z    defunct ("zombie") process, terminated but not reaped by its parent

所以最后我用管道将grep T$其表示为,在最后一列中显示所有具有T的过程。

然后,我有一个很好的列表,其中列出了处于停止状态的来自不同用户的所有进程。

$ ps -a -o pid,user,cmd,state | grep 'T$'
  865 joson74+ python                      T
  885 joson74+ sh -c less                  T
  886 joson74+ less                        T
 1014 minames+ python3.4 -i /home/minames  T
 5352 MooKo    nano stdio.h                T
 7851 harry    tmux attach                 T
12083 harry    tmux attach                 T
13495 gorylla+ python3.4 -i /home/gorylla1 T
18009 conr1d   vim                         T
19664 enythin+ python                      T
24906 wardlist python                      T

要使停止的作业附加到当前的shell,jobs -ps比这个答案要简单。话虽如此,这个答案并不仅仅显示通过Ctrl-Zshell 停止的作业,而是所有停止的作业:其他shell,其他用户,包括正在调试的作业(例如,由gdb进行调试)。
斯蒂芬·古里雄

对我来说最好的答案,但不是完全有效。我不得不用来ps -el | grep T查找状态为“ T”的进程。
dr0i

4

如果要删除一些已停止的作业,而不是全部,请尝试以下操作:

首先,列出工作,您将获得如下信息:

$ jobs -l

[2]   4813 Stopped                 ./parse < call.txt
[3]-  4819 Stopped                 ./parse < call.txt

将kill发送到已停止的作业,除了将其带入前台之外,它只会做排队,它将终止

$ fg %2
./parse < call.txt
Terminated

$ jobs -l
[3]-  4819 Stopped                 ./parse < call.txt

4

通常,如果收到该消息,则需要注销两次。例如,第一个Ctrl+D向您发出警告消息,通知您有关已停止的作业,第二次按下将使您注销杀死这些作业。这与logoutexit命令相同。

要手动杀了他们,试试:kill $(jobs -p)


如果不想从当前shell中终止作业,则可以使用disown命令从不删除作业的情况下将它们从活动作业表中删除。例如

$ sleep 1000 &
[1] 19404
$ jobs
[1]+  Running                 sleep 1000 &
$ disown

停止的作业还可以通过进程的状态(T字符)来确定,这意味着进程已通过诸如SIGSTOPSIGTSTP或其他(如SIGTTINSIGTTOU)的信号停止。

如果jobs没有shell内置命令,可以通过以下命令列出停止的进程:

ps wuax | awk '$8 ~ "T"'

要杀死所有这些,您基本上可以键入:

kill -9 $(ps wuax | awk 'NR>1 && $8 ~ "T" {print $2}')

这是一个简单的测试:

$ sleep 1000 &
[1] 2014
$ sleep 1000 &
[2] 2015
$ sleep 1000 &
[3] 2016
$ sleep 1000 &
[4] 2017
$ killall -STOP sleep
[1]   Stopped                 sleep 1000
[2]   Stopped                 sleep 1000
[3]   Stopped                 sleep 1000
[4]   Stopped                 sleep 1000
$ ps wuax | awk '$8 ~ "T"'
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
vagrant   2014  0.0  0.0   7228   832 pts/0    T    20:38   0:00 sleep 1000
vagrant   2015  0.0  0.0   7228   708 pts/0    T    20:38   0:00 sleep 1000
vagrant   2016  0.0  0.0   7228   760 pts/0    T    20:38   0:00 sleep 1000
vagrant   2017  0.0  0.0   7228   828 pts/0    T    20:38   0:00 sleep 1000
$ kill -9 $(awk 'NR>1 && $8 ~ "T" {print $2}' <(ps wuax))
$ jobs
[1]   Killed                  sleep 1000
[2]   Killed                  sleep 1000
[3]   Killed                  sleep 1000
[4]   Killed                  sleep 1000
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.