Why doesn't Ctrl-C kill the Terminal itself?

The terminal is running when we open it.

luvpreet@DHARI-Inspiron-3542:/$

I have just opened it. So, when I press Ctrl+C, why doesn't it kill itself and close the terminal??


Solution 1:

Ctrl+C is the interrupt signal. When you type this in a terminal, bash sends SIGINT to the job in the foreground. If there is no job (which is the case when you've just opened a terminal), nothing happens. The terminal emulator program is not a job running in the shell, so, it doesn't get the signal and doesn't close.

If you want to close the terminal with a control key, use Ctrl+D (EOF) which causes bash to exit (and closes the terminal too).

See also: Bash Beginner's Guide on signals and in more depth How signal handling works
note: this answer has been edited since comments were posted

Solution 2:

The ^C keystroke, like other keystrokes*, isn't magic--it sends a keycode to whichever program has focus. (In X, the keycode is 54 for the C with a modifier of 0x4 for Ctrl.) The program that's receiving the stream of keys is responsible for doing something appropriate with them--remember that in many GUI applications, the keystroke copies to the clipboard.

When a GUI terminal emulator (e.g., Konsole) or a virtual terminal receives a keystroke that it interprets as ^C, it can do one of three things. If the terminal is in raw mode, then the running program has asked the terminal not to perform any handling of special keys itself and to pass them straight to the program. Some programs that support advanced features like line editing receive keyboard input in some configuration in between complete raw keystrokes and processed lines of text; bash, for example, receives keystrokes one at a time. ^C is interpreted by the terminal, but the backspace key is sent to the shell as-is.

Most programs, however, use cooked mode (because it isn't raw), where the terminal interprets some basic keystrokes before actually sending them to the program (this is why you can use backspace in cat). In this mode, the terminal itself translates the ^C keystroke into a SIGINT signal and sends it to the child process. Since the terminal generated the signal, it will not get confused and terminate.

  • SysRq really is magic.

Solution 3:

^C is usually mapped (see stty -a) to the SIGINT signal (see man 7 signal).

An un-caught SIGINT interrupts the running process, BUT...

SIGINT is one of the signals that a process can specify behaviour for ("Catching a signal").

What you call "the terminal" catches SIGINT, and goes back to work.

Solution 4:

When I was a beginner I was missing the part that when I was using the command line I actually was using two seperate programs, a terminal and a shell (e.g. bash)

The shell is what you already probably know, a program that takes as input commands or scripts, executes them and prints their output.

The terminal on the other side is like a man in the middle between the user and a program (which program is usually a shell like bash or fish). What the terminal does is to read the input for example from the keyboard, maybe process that input in some way, and redirect it to the other program (bash).

Also this works in the other way too, when the other program outputs something, that something is redirected to the terminal, then it's the terminal's job to output that something to the screen. In between getting input and printing it to the screen the terminal can interpret the input it is getting in various ways.

For example if a program outputs the following sequence:

\e[0;31m some extra foobar text

The terminal will output to the screen "some extra foobar text" with red colored letters. This is because the terminal chooses to treat that weird code in a special way which code hints it to print the following output in red.

Similarly when the user presses Ctrl - C, the only special thing about this is that the terminal chooses to treat it in a special way, there is nothing other special about this key sequence. Specifically this hints it to sent the interrupt signal (SIGINT) to the process that is running inside the terminal, that is the shell. If at that moment exists any program that has been spawned by the shell and is currently running in the foreground it also receives the signal. Now the shell has a special handler for this signal and nothing happens. But most programs have the default handlers which in SIGINT's case just exit.