What is the difference in using Ctrl+D and Ctrl+C to terminate cat command?
Solution 1
When the cat
command is running, the terminal is in canonical input mode. This means, in short, that the terminal's line discipline is handling line editing, and is responding to all of the special characters configured for the terminal (viewable and settable with the stty
command).
The cat
command is simply read()
ing from its standard input until a read()
call returns zero bytes read, the POSIX convention for hitting end of file.
Terminals do not really have an "end". But there is a circumstance where read()
of a terminal device returns zero bytes. When the line discipline receives the "EOF" special character, whatever that happens to be configured as at the time, it causes read()
to return with whatever is in the editing buffer at that point. If the editing buffer was empty, that returns zero bytes read from read()
, causing cat
to exit.
cat
also exits in response to signals whose default actions are to terminate the process. The line discipline also generates signals in response to special characters. The "INTR" and "QUIT" special characters cause the INT
and QUIT
signals to be sent to the foreground process (group), which will be/contain the cat
process. The default action of these signals is to terminate the cat
process.
Which leads to the observable differences:
- Ctrl+D only has this action when it is the EOT special character. This is usually the case, but it is not necessarily the case. Similarly, Ctrl+C only has its action when it is the INTR special character.
-
Ctrl+D will not cause
cat
to terminate when the line is not in fact empty at the time. An interrupt generated by Ctrl+C will, though. - A naïve implementation of
cat
in the C language will block buffer standard output if it finds it directed at a file, as in the question. In theory, this could lead to buffered and not yet output lines being lost ifcat
is terminated bySIGINT
.In practice, the BSD and GNU C libraries implement a buffering mode that is not described in the C or C++ language standards. Standard output when redirected to file or pipe is smart buffered. It is block buffered; except that whenever the C library finds itself about to
read()
the beginning of a new line from any file descriptor that is open to a terminal device, it flushes standard output. (The BSD and GNU C libraries do not quite implement the same semantics and do more than this, strictly speaking, but this behaviour is a common subset.) Thus an interrupt signal will not cause lost buffered output whencat
is built on top of such a C library. - Of course, if
cat
is part of a command pipeline, some other process could be buffering the data, downstream ofcat
before those data reach an output file. So again when the line discipline sendsSIGINT
, which (by default) terminates all of the processes in the pipeline, input data buffered and not yet written will be lost; whereas terminatingcat
normally with the "EOF" special character will cause the pipeline to terminate normally, with all of the data passing to the downstream process before it receives an EOF indication from itsread()
of its standard input.
Note that this bears very little relationship to what happens when your interactive shell is reading a line of input from you. When your shell is waiting for input, the terminal is in non-canonical input mode, in which mode the line discipline does not do any special handling of special characters. How your shell treats Ctrl+D and Ctrl+C is entirely up to the input editing library that your shell uses (libedit, readline, or ZLE) and how that editing library has been configured (with key bindings and suchlike).
Further reading
- POSIX terminal interface. Wikipedia.
Solution 2
CTRL+C is an interrupt signal. It will stop the command.
CTRL+D is end of file or exit()
. When you entered CTRL+D , it exited from the command because of end of file. If you type CTRL+C in your shell nothing will happen. However, if your enter CTRl+D, it will exit from your current Shell in most systems.
Related videos on Youtube
![Sonevol](https://i.stack.imgur.com/eXwXu.jpg?s=256&g=1)
Sonevol
Sexually I am transsexual lesbian. Please consider me to be female and address me by "she" and "her" and be compassionate to my feelings. Pets are my love and my pet Bhutu (female balck and white tuxedo cat) means everything to me. Also I love my mom, my grand-mom and the girl named Puja. I also love the two children which Puja has. We six are almost family. I like UNIX and UNIX based operating systems. I love to play around with Linux and learn newer things. Professionally I am front end web developer working independently. Also I am a weed addict.
Updated on September 18, 2022Comments
-
Sonevol almost 2 years
I have the following two test files:
test1 test2
Both of them are blank. Now I issue the following commands:
$ cat > test1
Enter
This is a test file
Enter
Ctrl + D
$ cat > test2
Enter
This is another test file
Enter
^C
Ctrl + C
$
Now I check the contents of the two files
$ cat test1 This is a test file $ cat test2 This is another test file $
So is there any real difference in the outcome if we use the above two methods to achieve the same outcome?
-
JdeBP almost 7 yearsA related question is unix.stackexchange.com/questions/177651 .
-
-
Sonevol almost 7 yearsApart from what are they according to definition is there any change in outcome or the outcome will always be the same, whichever method you use?
-
user996142 almost 7 years@Sonevol different. CTRL+D works like EOF and CTRL+C is intr (check
stty -a
for these settings of line discipline). Trycat > foo.txt
. Type something, click CTRL+D and checkfoo.txt
. Check it with CTRL+C then.