当我尝试从Linux服务器退出时,收到消息:

有停止的作业。

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

评论

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

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

再次按ctrl + d,它将使您现在退出,从而杀死进程中的那些作业。

#1 楼

要快速杀死bash下的所有已停止作业,请输入:
kill -9 `jobs -ps`


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

评论


-1为“杀死工作”

–user81458
2012年8月10日在21:44

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

–user13107
2012年10月27日18:12



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

–slm
2014年4月12日20:18在

杀死-9将达到目的。

– timetofly
2014-10-12 17:36

#2 楼

尝试输入以下内容:

kill -9 $(jobs -p)


评论


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

– rems
2011-02-25 10:49



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

–user131776
2012年8月10日在21:33

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

– Paul Gear
14年7月22日在23:59

在zsh上不起作用。由于zsh不兼容POS IX作业。

–Max Coplan
18-10-27在0:38



那么,如何处理zsh?

–fx-kirin
19 Mar 1 '19 at 5:49

#3 楼

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

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


评论


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

–laebshade
2015年10月20日下午13:35

接受的答案上的-s参数仅过滤已停止的答案

–79E09796
17年12月29日在10:45

#4 楼

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

评论


这将发送一个HUP,它不一定会停止任何作业。

–斯蒂芬·尼德斯基(Stephen Niedzielski)
14年6月28日在2:27

#5 楼

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


评论


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

– drcelus
13年2月26日在10:54

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

– Dunxd
13-2-26在11:39



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

– monu
13年2月27日在6:01

#6 楼

通常,如果收到该消息,则需要注销两次。例如。首先Ctrl + D会向您显示警告消息,以通知您有关已停止的作业的信息,第二次按下将使您注销杀死这些作业的信息。这同样适用于logoutexit命令。

要手动杀死它们,请尝试:kill $(jobs -p)


如果您不想杀死自己的工作,当前的shell,您可以使用disown命令将它们从活动作业表中删除而不杀死。例如,
$ sleep 1000 &
[1] 19404
$ jobs
[1]+  Running                 sleep 1000 &
$ disown




也可以通过进程的状态(字符T)确定停止的作业,这意味着该进程已被诸如SIGSTOP之类的信号停止, SIGTSTP或其他(例如SIGTTINSIGTTOU)。

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

ps wuax | awk ' ~ "T"'


要杀死它们,基本上可以键入:

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


这里是一个简单的测试:

$ 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 ' ~ "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 &&  ~ "T" {print }' <(ps wuax))
$ jobs
[1]   Killed                  sleep 1000
[2]   Killed                  sleep 1000
[3]   Killed                  sleep 1000
[4]   Killed                  sleep 1000


#7 楼

以防万一这对其他人有帮助-大多数人在这里是因为他们启动了一些已停止的进程,也许是通过shell后台运行的。我需要找到以root用户身份被其他用户停止的进程,而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-Z停止的作业,而是所有停止的作业:其他Shell,其他用户,包括正在调试的作业(例如通过gdb)。

–StéphaneGourichon
18年5月25日在7:50

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

–dr0i
19年2月1日在8:28

#8 楼

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

首先,列出作业,您将获得类似以下内容的信息:

$ 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