多次按ctrl-c可以使正在运行的程序更快地关闭吗?


41

我经常开始读​​取一个大文件,然后想在一段时间后退出,但是从按
Ctrl+ C到程序停止有一个滞后。是否可以通过几次按Ctrl+ C键来缩短延迟?还是我在浪费按键?


我注意到在运行调用各种子进程的进程时,Ctrl-C有时会中断正在运行的子进程,但不会中断父进程。在中确实如此bash,但zsh始终关闭父级的情况却并非如此。这是我喜欢的原因之一zsh
joeytwiddle 2014年

17
是的,就像反复按电梯按钮或人行横道按钮一样,将导致电梯提早到达或灯快变绿。
Michael

3
是的,就像电梯和人行横道按钮一样,CTRL-C也会发粘或生锈,或产生不稳定的连接。多按几次是一个好方法,因为只需按一次就可以注册电梯,步行标志亮起或程序关闭。
hippietrail 2014年

1
@hippietrail,但您的外壳^C在注册印刷机时会打印出来(至少bash
会这样做

1
就其价值而言,我不认为这浪费了我的按键操作-我认为它以一种无损的方式发泄了一些挫败感。(我通常会打2-3次,但这部分是因为我在电话线上连接的终端上“长大”,在这些终端上您不能总是指望每次到达机器的按键。)
keshlam 2014年

Answers:


35

在第一个之后Ctrl-C,程序将接收SIGINT并通常开始清理(删除tmp文件,关闭套接字等)。如果Ctrl-C在此过程中再次击打,则可能会打断清理例程(即,可能会作用于其他信号而不是一个人),从而留下一团糟。虽然这通常不是这样的,比较常用的附加信号在事实上发送该过程完成(由于操作员与系统交互的固有延迟)。这意味着信号被另一个进程(通常是shell,但并非总是)接收。如果该接收者不能正确处理此信号(像shell通常那样-参见Jenny D的回答),您可能会对这种操作的结果感到不满意。


为什么要中断清理程序?这只是INT该过程收到的另一个信号。
混乱

4
@chaos为什么要这样?如果清理例程已挂断并且您想停止它,则应该这样做。它实际上以这种方式工作吗?是的,很多时候。您可以简单地演示它:用一行制作一个bash脚本trap "sleep 20 || echo clean up cancelled!" EXIT ; sleep 10。运行脚本,然后按ctrl-C两次。您将看到第二个ctrl-C被传递到“清除”例程(在trap语句中)并终止其sleep命令。
John1024

1
@ John1024啊,现在我明白了。感谢脚本片段^^但是,清除并没有取消,请参阅:trap "sleep 20 || echo clean up cancelled!; sleep 10; echo 'but continued'" EXIT ; sleep 10只是sleep获得信号的命令。我们俩都错了xD
混乱

2
不对 信号传递是同步的。如果isig为on,则内核按下并接收CTRL-C时(对于终端仿真器,只要终端仿真器将其写入到伪终端的主端),就会将SIGINT信号发送到所有终端的前台进程组中的进程。它可能在此处被阻止,但是以后将不会传递给另一个进程。即使终端设备缓冲区已满(应用程序尚未读取您键入的任何内容),CTRL-C也会跳过队列。
斯特凡Chazelas

1
是的,例如,VLC将多个Ctrl + C信号解释为不干净退出的一种方式,而单个Ctrl + C将尝试干净退出。
杰里米·维瑟

11

你是在浪费他们。发生的所有事情是,一旦服务器完成屏幕输出,它将收到多个消息Ctrl-C。第一个将用于终止该进程,而下一个将终止于您的shell中,然后看起来像

[user@server]$ ^C
[user@server]$ ^C
[user@server]$ ^C
[user@server]$ ^C
[user@server]$ ^C
[user@server]$ 

6
发送SIGINT时,进程不一定会退出。它可以无限期地保持生命,并且每次按Ctrl + C都会执行不同的操作。
Brian Gordon

真正。我在假设用户如何读取文件。
珍妮·D

5

简短的答案:如果该过程对此有反应。

答案:当您点击ctrl+时c,内核会向进程发送信号。可以通过以下命令确定哪个信号:

user@host:~# stty -a | grep -i "\^C"
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;

参见手册页stty

   intr CHAR
          CHAR will send an interrupt signal

它是信号INT,也称为数字2。当进程具有信号处理程序时,它可以对此做出反应。大多数进程都会执行一些清理作业以成功结束。


Ctrl-Z通常发送可以处理的SIGTSTP(与SIGSTOP不同)。
彼得2014年

4
不,不是将SIGINT发送到进程的外壳。是kernel(终端的线路规程,终端驱动程序)将SIGINT发送到终端的前台进程中的每个进程。
斯特凡Chazelas

将来的读者也请参见unix.stackexchange.com/a/120071/135943
通配符

4

你是对的。按键被浪费了。按下Crtl+C并检测到它时,有一些资源需要清除,这就是为什么要花费一些时间的原因。我知道Ctrl+C需要按一下的一种可能情况是,当您想取消Yum更新过程时,Yum要求您按Ctrl+C两次以确认您确实要取消。


2

尽管Ctrl-C在一般情况下只需要一个,但在某些情况下可能是必须的。例如,Python Ctrl-C会在生成新线程时捕获陷阱,因此,如果在启动多个线程的过程中出了点问题,则有必要多次重发它,以便它可以直接进入python父进程抓住。


1
这在我创建多线程/处理的python脚本时不时发生。有时,在终止主要过程之前,需要几次压机。
狮子座

0

总是必须按Ctrlc几次。我从未在第一次按下时就做出回应,而不得不多次使用它,直到系统真正意识到有人Ctrlc正在发送。好像实际上实际上错过了/丢失了大多数。

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.