cat
concatenates files given as arguments on command line to standard output, it reads bytes at a time an as default does not perform any interpretation of the bytes it reads.
In your first example you are redirecting stdout to a file, that's why you get a new file.
In your second example the bytes are written to the terminal, and it is the terminal which is interpreting sequences of characters as control sequences for the terminal, this is why you get unusual behaviour on your terminal. It has nothing to do with cat
as such, cat
doesn't know what you are going to do with it's output. You might be sending it through a pipe to another program to interpret/process/print or play "Singing in the rain".
So following the unix philosophy,
do one thing, do one thing only, but do it well
cat
should not attempt to second guess what you are trying to do.
edit 1 reply to @kiwy's 1st comment below.
Yes and No, let me explain,
No, if you cat
to a terminal, because it (the terminal software) is sending the output to your screen or interpreting control sequences (it is emulating an old piece of hardware ie. a teletype device).
but,
Yes if you cat to a pipe and the program recieving can interpret the characters as commands.
look cat this for an example, cat anyOldShellScript | bash
bash will interpret what it gets as commands.
Because of the order how things are done.
When you do:
cat abc > abc
>
is the output redirection operator, when the shell sees this it opens the file in truncation mode using O_TRUNC
flag with open(2)
i.e. open("abc", O_TRUNC)
, so whatever was there in the file will be gone. Note that, this redirection is done first by the shell before the cat
command runs.
So when the command cat abc
executes, the file abc
is already truncated hence cat
will find the file empty.
Best Answer
It may be useful to explain how files work at the lowest level:
A file is a stream of bytes, zero or more in length. A byte is 8 bits. Since there are 256 combinations of 8 bits, that means a byte is any number from 0 to 255. So every file is, at its lowest level, a big hunk of numbers ranging from 0 to 255.
It is completely up to programs and users to decide what the numbers "mean." If we want to store text, then it's probably a good idea to use the numbers as code, where each number is assigned a letter. That's what ASCII and Unicode do. If we want to display text, then it's probably a good idea to build a device or write a program that can take these numbers and display a bitmap looking like the corresponding ASCII/Unicode code. That's what terminals and terminal emulators do.
Of course, for graphics, we probably want the numbers to represent pixels and their colors. Then we'll need a program that goes through the file, reads all the bytes, and renders the picture accordingly. A terminal emulator is expecting the bytes to be ASCII/Unicode numbers and is going to behave differently, for the same chunk of bytes (or file).