106
  1. In Bash, I learned that the ending signal can be changed by here document. But by default how can I signal the end of stdin input?
  2. I happened to find that with cat and chardet, their stdin inputs can be signaled as finished by Ctrl+D. But I seems to remember that Ctrl+D and Ctrl+C are similar to ending execution of a running command. So am I wrong?
AdminBee
  • 22,803
Tim
  • 101,790

3 Answers3

157

Ctrl+D, when typed at the start of a line on a terminal, signifies the end of the input. This is not a signal in the unix sense: when an application is reading from the terminal and the user presses Ctrl+D, the application is notified that the end of the file has been reached (just like if it was reading from a file and had passed the last byte).

Ctrl+C does send a signal, SIGINT. By default SIGINT (the interrupt signal) kills the foreground application, but the application can catch the signal and react in some different way (for example, the shell itself catches the signal and aborts the line you've begun typing, but it doesn't exit, it shows a new prompt and waits for a new command line).

You can change the characters associated with end-of-file and SIGINT with the stty command, e.g. stty eof a would make a the end-of-file character, and stty intr ^- would disable the SIGINT character. This is rarely useful.

Kusalananda
  • 333,661
  • Thanks! DoesCtrl+D mean Ctrl and capital D or it doesn't matter? – Tim Jul 09 '11 at 16:31
  • 11
    @Tim: it's lower case you want ... the convention of writing keyboard commands with capitals comes because the labels on the keyboard are always in capitals and the thing being described is a KEY SEQUENCE not the actual character code that the program sees. Yes this is confusing sometimes. – Caleb Jul 09 '11 at 16:32
  • @Caleb: Thanks! How shall one specify that the key is in capital? Or is there ever such case? – Tim Jul 09 '11 at 16:37
  • 2
    @Tim On a terminal, the key combinations Ctrl+Shift+D and Ctrl+D send the same character anyway (character number 4, usually called Ctrl+D). – Gilles 'SO- stop being evil' Jul 09 '11 at 16:41
  • @Tim: When specifying a key sequence to be entered by the user you would customarily include Shift in the sequence description as in Gilles' example above. – Caleb Jul 09 '11 at 17:35
  • @Gilles: Now I see that Ctrl+D doesn't generate a signal, but is the end-of-transmission character. When typing Ctrl+D, is the end-of-transmission character read into the program that takes the stdin input, and used by the program to detect if the program has reached the end of transmission/fie? Or is the EOF character only seen by the shell to detect the end of transmission/file, before passing the stdin input to the program, and the EOF character is never passed into the program? – Tim Mar 03 '16 at 16:54
  • 2
    @Tim The terminal received Ctrl+D. It does not send a character to the program. What happens is that when the program reads from the terminal, the terminal tells it “this is the end of the file”, same as when a program tries to read after the end of a disk file. The shell is not involved at all. – Gilles 'SO- stop being evil' Mar 03 '16 at 17:02
  • Thanks. (1) So is the program not implemented to deal with the character of ctrl+D? Is it correct that ctrl+D is a control character, only meaningful to the terminal, not to the shell, the program or the Linux kernel? (2) How does the terminal notify the program the end of file? by a signal, a character, or ...? – Tim Mar 03 '16 at 18:03
  • @Tim Ctrl+D is interpreted as the ASCII control character EOT (end of transmission) when the sequence of key it is not caught by the terminal. To enter the EOT character, you can prevent the interpretation by the terminal by first sending Ctrl+V and then Ctrl+D (Ctrl+V makes that the next character is passed quoted, preventing it from being interpreted by the terminal) – see man stty and stty -a. – The Quark Oct 31 '21 at 17:13
28

Your second point lumps two completely different things together.

  • Ctrl+C sends a kill signal to the running process.
  • Ctrl+D sends an End of Transmission character.

You are looking for the latter.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Caleb
  • 70,105
  • 14
    Potential for confusion here: from the application perspective, no any actual character is sent for ^D. Which means that the application doesn't recieve that character from the read(2) syscall. – ulidtko Jan 22 '13 at 17:59
1

I encountered this while searching for other information. The answers provided are correct but I think too involved with the internal workings.

The simple, non-technical, answer is that Ctrl+D terminates the STDIN file and that Ctrl+C terminates the active application.

Both are handled in the keyboard driver and apply to all programs reading from the keyboard.

To see the difference start a command line shell and enter the wc command with no arguments. It is now waiting for STDIN input. Type a sentence and "return". Now type Ctrl+D and wc will complete and give you the line, word and character count.

Do the same thing but type Ctrl+C. wc will terminate with no output.

FargolK
  • 1,667
  • I do not think that either Ctrl+D and Ctrl+C are handed by the keyboard driver since their interpretation as EOF or SIGINT is a configurable terminal setting (see man stty and stty -a) – The Quark Oct 31 '21 at 17:20