我有一些Stopped
后台进程。
kill $(jobs -p)
并且kill `jobs -p`
没有效果
kill %1
、kill %2
等成功终止各个进程
如何用一个命令杀死所有后台进程?
另外,为什么前两个命令对我不起作用?
我正在运行 Linux Mint 15, 64 位
答案1
当他们奔跑时
似乎你可以用 的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
好吧,这并没有杀死它们,但那是因为进程本身无法处理终止信号,它被停止了。因此,请告诉操作系统进行杀戮。这就是 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
。
答案2
你可以试试这个。
for x in `jobs -p`; do kill -9 $x; done
但是,如果您想终止该进程,可以发出以下命令:
for x in `jobs -p`; do kill -15 $x; done
来自维基百科命令页面Kill
,
一个进程可以发送一个信号术语以四种方式发出信号(在本例中进程 ID 为“1234”):
kill 1234
kill -s TERM 1234
kill -TERM 1234
kill -15 1234
该过程可以发送信号杀死三种方式发出信号:
kill -s KILL 1234
kill -KILL 1234
kill -9 1234
正如中所解释的这答案,这就是区别终止和杀。
终止信号,信号术语,是一个可以在程序中拦截的信号。通常,在后台运行的进程会捕获此信号并启动关闭进程,从而干净退出。杀戮信号,信号杀死,无法拦截。当它被发送到进程时,将导致该程序突然终止。
例如,当您关闭或重新启动计算机时,通常会出现信号术语首先发送到正在运行的进程,如果它们支持的话,允许它们以干净的方式退出。然后,几秒钟后信号杀死被发送到仍在运行的进程,以便强制释放正在使用的资源(例如正在使用的文件)并且关闭序列可以继续(例如卸载文件系统)。
答案3
好的,玩弄这个我发现,当您终止一个已停止的作业(其中执行已暂停但未终止)时,它不会完成,直到它被带入前台。通常通过按终端上的Ctrl-来停止程序。Z大多数终端在这种情况下发送SIGSTOP
,但当然也有其他发送方式,例如使用kill -STOP
或kill -19
。
程序不会立即完成是正常行为,因为程序必须运行才能处理SIGTERM
发送的默认信号kill
。此外,有时在bash
发送SIGTERM
到后台进程后,它会以某种方式最终停止(尽管SIGTERM
仍处于挂起状态)。
完成所有工作的最安全方法(没有诉诸kill -9
) 首先发送SIGTERM
普通的kill
,然后发送SIGCONT
到任何剩余的作业,例如:
kill $(jobs -p)
kill -18 $(jobs -p)
SIGCONT
(是信号号18
)会将任何停止的作业带到前台,以便它们可以SIGTERM
像平常一样处理。
如果所有程序都没有完成此操作,那么您可以尝试其他一些信号,通常可以在诉诸kill -9
.我推荐的第一个是SIGHUP
因为许多程序通常会阻止其他终止信号响应SIGHUP
。这通常在控制终端关闭时发送,特别是在ssh
会话结束时发送tty
。许多交互式程序(例如 shell)不会响应其他终止信号,但会响应此信号,因为它们在ssh
会话结束后(或任何控制终端关闭后)保持运行将是一个问题。要尝试这个你可以这样
kill -1 $(jobs -p)
kill -18 $(jobs -p)
当然,您需要再次确保程序没有停止,以便它可以处理信号。您可以尝试的其他终止信号有SIGINT
( kill -2
) 和SIGQUIT
( kill -3
)。但当然,尝试全方位的好处会减少,并可能导致不可避免的情况SIGKILL
(又名kill -9
)。
答案4
这将一一终止当前 shell 中的所有作业:
while kill %; do :; done
解释:%
指的是列表中的最后一项作业,因此它将循环直到kill
返回非零值,这意味着没有更多作业需要终止。
另一种方法可能是先发送SIGTERM
,然后SIGCONT
您的工作可以继续,他们要做的第一件事就是接收您的SIGTERM
.
/bin/kill $(jobs -p) && /bin/kill -CONT $(jobs -p)
(由于某种原因内置的kill
很奇怪,所以我在这里使用了外部的)。