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??
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It only takes a minute to sign up.
Sign up to join this communityThe 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??
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
bash
will terminate any programs when ctrl-c is pressed. It will just tell the kernel which process group is active and the kernel will generate a signal to that process group when it receives ctrl-c from the terminal program.
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.
Ctrl
+Alt
+Delete
in the Windows world, where the key combination is pretty close to magic (it can be used to get Windows to work, that's pretty magical in and of itself!), since it's hard-coded into the system to interrupt and override pretty much everything—pretty similar to SysRq
in that sense.
cbreak
/-icanon
, but it does leave the isig
mode set, and does receive real signals when you press keys that are mapped to them. It handles SIGINT
by behaving as you described (it doesn't just cancel line editing, it also cancels any internal command that may be running in a loop), and completely ignores SIGTSTP
and SIGQUIT
. Other programs, such as vi, may not.
Mar 7, 2017 at 19:55
Ctrl
+Alt
+Delete
used to be even more magic than it is today - blogs.msdn.microsoft.com/oldnewthing/20140912-00/?p=44083 . Though I'm a Linux person at heart I'm often considerably awed by the extent Windows went to make things user-friendly and logical with such limited resources in the early days.
^c
won't kill the window manager :). Not able to comment on raw/cooked character at a time stuff, but the answer is spot on about how that keystroke is generating SIGINT
^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.
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.
Every signal has a default action associated with it. The default action for a signal is the action that a script or program performs when it receives a signal.
Ctrl+C sends the "interrupt" signal (SIGINT), which defaults to terminating the process to the job running in the foreground.
Ctrl+D tells the terminal that it should register a EOF on standard input, which bash interprets as a desire to exit.
A process can choose to ignore the INT signal, and Bash does so when it's running in interactive mode.
From the manual:
When bash is interactive, in the absence of any traps, it ignores SIGTERM (so that kill 0 does not kill an interactive shell), and SIGINT is caught and handled (so that the wait builtin is interruptible). In all cases, bash ignores SIGQUIT. If job control is in effect, bash ignores SIGTTIN, SIGTTOU, and SIGTSTP.
trap is a function built into the shell that responds to hardware signals and other events. It defines and activates handlers to be run when the shell receives signals or other special conditions.
trap [-lp] [arg] [sigspec …]
-l
print a list of signal names and their corresponding numbers.
-p
display the trap commands associated with each SIGNAL_SPEC.arg are to be read and executed when the shell receives signal sigspec. Each sigspec is either a signal name or a signal number. Signal names are case insensitive and the SIG prefix is optional.
If a sigspec is 0 or EXIT, arg is executed when the shell exits. To understand it, close terminal & open it after editing following line in .bashrc
file.
trap 'notify-send "Ctrl D pressed"' 0
Ctrl D is similar to exit
command to exit from terminal.
If you want Bash to exit upon receiving the INT signal, even in interactive mode, you can add the following to your ~/.bashrc
:
trap 'exit' INT
or
trap 'exit' 2