41

I often start to read a huge file and then want to quit after a while, but there is a lag from pressing
Ctrl+C to the program stops. Is there a chance of shortening the lag by pressing the Ctrl+C key several times? Or am I wasting my keypresses?

  • I have noticed when running a process that calls various child processes, Ctrl-C will sometimes interrupt the running child, but not the parent process. That is true in bash, but not the case in zsh which always closes the parent. It is one of the reasons I like zsh. – joeytwiddle Jan 15 '14 at 15:27
  • 17
    Yes, just like pressing the elevator button or the cross-walk button repeatedly will cause the elevator to come sooner or the light to turn green quicker. – Michael Jan 15 '14 at 15:40
  • 3
    Yes just like elevator and crosswalk buttons, CTRL-C can also get sticky or rusty or develop iffy connections. Pressing more times is a good tactic because only one press has to register for the elevator to come, the walk sign to light up, or the program to close. – hippietrail Jan 15 '14 at 17:40
  • It was never wasted effort to smack your old (cathode ray tube) TV in case it didn't work, it was good to let off some steam. I view hammering Ctrl+C in much the same light (same goes for Esc). ;-) – Frerich Raabe Jan 15 '14 at 23:05
  • 1
    @hippietrail but your shell will print out ^C when it registers the press (at least bash does) – wchargin Jan 15 '14 at 23:05
  • 1
    For what it's worth, I don't consider it wasting my keypresses -- I consider it venting some frustration in a non-damaging way. (I usually hit it 2-3 times, but that's partially because I "grew up on" terminals attached over phone lines where you couldn't always count on every single keystroke reaching the machine.) – keshlam Jan 16 '14 at 03:16

6 Answers6

35

After the first Ctrl-C, the program will receive SIGINT and usually starts cleaning up (deleting tmp files, closing sockets, etc.). If you hit Ctrl-C again while that is going on, it may happen that you interrupt the clean up routine (i.e. the additional signal might be acted upon instead of being left alone), leaving a mess behind. While this usually is not the case, more commonly the additional signals are in fact sent after the process finished (because of the inherent delays in the interaction of the operator with the system). That means that signals are received by another process (often shell, but not always). If that recipient doesn't handle this signal properly (like shell usually does - see Jenny D's answer) you may be unpleasantly surprised by the outcome of such an action.

peterph
  • 30,838
John1024
  • 74,655
  • Why should it interrupt the clean up routine? It's just another signal INT that the process recieves. – chaos Jan 15 '14 at 08:18
  • @chaos makes more sense now? – peterph Jan 15 '14 at 08:40
  • 4
    @chaos Why should it? It should if the clean up routine has gotten hung up and you want to stop it. Does it actually work this way? Yes, quite often. You can demonstrate it simply enough: make a bash script with the single line trap "sleep 20 || echo clean up cancelled!" EXIT ; sleep 10. Run the script and hit ctrl-C twice. You will see that the second ctrl-C is passed to the "clean up" routine (in the trap statement) and terminates its sleep command. – John1024 Jan 15 '14 at 08:43
  • 1
    @John1024 Ah, now I see it. Thanks for the script snippet^^ But, the cleanup is not cancelled see: trap "sleep 20 || echo clean up cancelled!; sleep 10; echo 'but continued'" EXIT ; sleep 10 It's just the sleep commands that get the signals. We were both wrong xD – chaos Jan 15 '14 at 08:53
  • @chaos. Yes, OK. The clean up wasn't cancelled but a command doing the 'clean up' was cancelled. – John1024 Jan 15 '14 at 09:00
  • 2
    That's incorrect. Signal delivery is synchronous. If isig is on, as soon as CTRL-C is pressed and received by the kernel (for a terminal emulator, as soon as the terminal emulator writes it to the master side of the pseudo-terminal), the SIGINT signal is sent to all the processes in the foreground process group of the terminal. It may be blocked there, but it's not going to be delivered later to another process. Even if the terminal device buffer is full (the applications have not read any of the things you typed), the CTRL-C will jump the queue. – Stéphane Chazelas Jan 15 '14 at 11:05
  • 1
    Yes, as an example, VLC interprets multiple Ctrl+C signals as a way to quit uncleanly, whereas a single Ctrl+C will attempt to quit cleanly. – Jeremy Visser Jan 15 '14 at 23:05
  • @John1024 - congrats on 3k! – slm Apr 29 '14 at 05:02
11

You're wasting them. All that happens is that once the server finishes with the screen output, it will receive multiple Ctrl-C. The first one will be used to kill the process, and the following ones will end up in your shell, which will then look something like

[user@server]$ ^C
[user@server]$ ^C
[user@server]$ ^C
[user@server]$ ^C
[user@server]$ ^C
[user@server]$ 
peterph
  • 30,838
Jenny D
  • 13,172
  • 6
    The process doesn't necessarily exit when sending it a SIGINT. It could stay alive indefinitely and do something different every time Ctrl+C is pressed. – Rag Jan 15 '14 at 19:44
  • True. I was making assumptions about how the user is reading the file. – Jenny D Jan 16 '14 at 08:45
5

Short answer: If the process reacts to it.

Long answer: When you hit ctrl+c the kernel sends a signal to the process. Which signal can be determined by the following command:

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

See the man page of stty:

   intr CHAR
          CHAR will send an interrupt signal

It's the signal INT, also known as number 2. When the process has a signal handler it can react to this. Most processes do some cleanup jobs to end successfully.

chaos
  • 48,171
  • Ctrl-Z usually sends SIGTSTP which can be handled (unlike SIGSTOP). – peterph Jan 15 '14 at 08:33
  • 4
    No, it's not the shell that sends the SIGINT to the process. It's the kernel (the line discipline of the terminal, the terminal driver) that sends SIGINT to every process in the foreground process group of the terminal. – Stéphane Chazelas Jan 15 '14 at 10:07
  • Future readers, also see http://unix.stackexchange.com/a/120071/135943. – Wildcard Mar 12 '17 at 08:01
4

You're right. The keypresses are being wasted. When you press Crtl+C and it gets detected, there are resources that need to be cleared, which is why it takes time. The one possible case I know where pressing Ctrl+C is required, is when you want to cancel a Yum update process, where Yum requires you to press Ctrl+C twice to confirm that you really want to cancel.

peterph
  • 30,838
Nav
  • 379
2

Although only one Ctrl-C is necessary in the general case, there are some situations where it may be necessary. Python, for example, traps Ctrl-C when a new thread is being spawned, and so if something goes wrong in the midst of starting up many threads, it is necessary to resend it multiple times in order for it to get through to the python parent process without being caught.

  • 1
    This happens to me now and then when I create multi-threaded/processed python scripts. Sometimes several presses are needed before the main process is killed. – Leo Jan 16 '14 at 06:11
0

I always have to press Ctrlc multiple times. I have never had it respond on the first press, and have to use it multiple times until the system actually realizes there's a Ctrlc being sent. Seems as though it actually misses/loses most of them.

jasonwryan
  • 73,126