Ctrl + C无法终止进程时该怎么办?


171

Ctrl+ C并不总是能杀死当前进程(例如,如果该进程在某些网络操作中很忙)。在这种情况下,您只需在光标处看到“ ^ C”,就不能做其他事情了。

使该过程立即终止而又不丢失我的终端的最简单方法是什么?

答案总结: 通常,您可以Ctrl+ Z使进程进入睡眠状态,然后执行kill -9 _process-pid_,使用ps和其他工具找到进程的pid 。在Bash(可能还有其他Shell)上,您可以轻松执行kill -9 %1(或通常为'%N')。如果Ctrl+ Z不工作,你必须打开另一个终端和杀死从那里。


screen将是一个可能的解决方案,允许您创建一个新窗口并kill从此处创建过程。
鲍比(Bobby)

2
假设您已经在屏幕上了:)
Dustin Boswell

Answers:


119

要了解为什么Ctrl+ C无效的问题,了解按一下会发生什么非常有帮助:

大多数外壳将Ctrl+ 绑定C为“向当前在前台运行的程序发送SIGINT信号”。您可以通过man signal了解不同的信号

 SIGINT        2       Term    Interrupt from keyboard

程序可以忽略该信号,因为它们也可以忽略SIGTSTP

 SIGTSTP   18,20,24    Stop    Stop typed at tty

(按Ctrl+时Z,大多数shell都会执行此操作,因此不能保证它可以正常工作。)

有一些信号不能被进程忽略:SIGKILLSIGSTOP等。您可以通过kill命令发送这些信号。因此,要杀死您的挂起/僵尸进程,只需找到进程ID(PID)。例如,使用pgrepps,然后使用kill它:

 % kill -9 PID

13
仅此而已。请注意,“僵尸”从技术上讲是一种过程状态,它与您在此处所说的“僵尸”所指的含义不同。(尚未被其父节点等待(终止)的终止进程处于zombie(Z)状态。在这种情况下,它不再能够处理信号。)
StéphaneGimenez,

遗憾的是,有时ctrl + c,ctrl + z和ctrl + \都不起作用,并且该进程正在运行undo sudo(允许无密码),因此您不能只是向该进程发送信号。
迈克尔

112

如果Ctrl+ C(SIGINT)不起作用,请尝试Ctrl+ \(SIGQUIT)。然后尝试Ctrl+ Z(SIGTSTP)。如果返回到外壳程序提示符,请kill对进程ID执行操作。(默认为SIGTERM信号,您可以用指定kill -TERM。在一些炮弹,你可以使用%1来指代PID)。如果不工作,去到另一个终端或SSH会话并做killkill -TERM上进程ID。 只有在万不得已,你应该做的kill -KILL,又名kill -9,因为它不会给过程中的任何机会,干净利落地退出,其同步打开文件,删除临时文件,关闭网络连接等。


32

按Ctrl-Z 暂停程序并将其置于后台

Suspend the program currently running and put it in the background.
This does not stop the process as it does in VMS!

(使用再次恢复到前台fg

然后,你可以killkill -9它,因为它的进程ID(你从ps a)。


13
使用bash可以使用kill $!,这$!是一个特殊变量,其中包含最后一个后台程序的pid。
Lloeki 2011年

@Lloeki对我不起作用(至少不可靠)。我必须bg在变量获取值之前一次。
丹尼尔·贝克

2
@丹尼尔,对。正如我所说的最后一个后台进程,因此bg仅在Ctrl + Z之后才需要将其暂停。
Lloeki 2011年

2
注意:这不仅仅是一个技巧,如果运行多个具有相同名称的进程,则使用psoutput(或killall)的风险很大。ps -e -o pid,command将提供pid + full args,不仅提供程序名称,而且可能还不足以区分。相比之下$!,肯定会成功。
Lloeki 2011年

1
@Lloeki我不同意。ps a我系统上的示例输出行:您在同一tty()中运行了多少个相同命令()的27721 s000 T 0:00.09 top暂停(T,我认为)实例?tops000
丹尼尔·贝克


13

通常,您仍然可以停止该过程(Ctrl+ Z),然后使用kill -9。对于kill -9,您首先需要过程PID。对于后台作业,这kill -9 %1是最简单的方法-如果不确定要杀死多少后台作业,请运行jobs

另外,您可以使用

ps

那你就可以跑

kill -9 <Appropriate PID from ps output>

5

Bash(和其他shell?)的一个更简单的解决方案是:

Ctrl-z      followed by     kill -9 %1

其中'%1'表示被杀死的作业号。如果您已经有其他作业处于休眠状态,则可能是'%2'(或其他)。当您按Ctrl-z时,您可以看到它是哪个工作编号:

[1]+  Stopped                 <process name>

请注意,“ kill”是shell的kill版本,不是/ bin / kill。


4

1)如果您在控制台上且处于多用户模式,则可以按CTRL-ALT-Fn并在另一个屏幕上登录,使用ps -ef | grep <myprocessname>pidof <myprocessname>,然后按ID号终止-9。

2)如果您是远程连接,请通过另一个终端会话进行相同的操作。

您还可以通过安装htop来简化生活,它是top的一种更通用的版本,它允许您有选择地终止正在运行的进程。大多数发行版都在回购中添加了htop。

3)如果您只是停留在挂起的ssh会话中(例如,连接到另一个系统),请尝试按代号(〜)(即转义键),然后按CTRL-Z返回到主机会话,然后您可以杀死卡住的ssh进程或等待它超时,大多数情况下,在一段时间的不活动后,ssh都会这样做。


0

如果您正在使用tmux或screen,但上述方法均无效<prefix> x,则仍然可以通过杀死窗格,然后该进程也会被杀死。


0

/ etc / profile中可能有一个用SIGINT(2)设置的陷阱。如果是这样,请将其删除。注销并重新登录,您应该会很好。

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.