Before getting into the details of command interpretation, I thought I'd
give a very simple example of why it's important. Here's an error
that occurs all the time. Let's say you have two files, called
file1
and file2
. You want to create a new version of
file1
that has file2
added to the end of it. That's what
cat
is all about, so you give the command:
% cat file1 file2 > file1
...wrong
This looks like it should work. If you've ever tried it, you know it
doesn't; it erases file1
, and then dumps file2
into it.
Why?
The shell (not cat
) handles standard input and output.
As the shell is processing the command, it sees that you're
redirecting standard output into file1
, so it opens the file for
writing, destroying the data that's already in it.
Later, after it's
finished interpreting the command line, the shell executes cat
,
passing file1
and file2
as arguments. But file1
is
already empty.
cat
reads file1
(which is empty) and
writes it on standard output (which goes into file1
).
cat
reads file2
(which also goes into file1
). At
this point, cat
is finished, so it exits.
file1
and file2
are identical, which isn't what
you wanted. But it's what you got.
Some versions of cat
give you a warning message in
this situation
(cat: input file1 is output
). This might lead you to believe that
somehow cat
was smart and managed to protect you. Sadly, that's
not true. By the time cat
figures out that an input file and an
output file are the same, it's too late: file1
is already gone.
This bit of cat
ty cleverness does have a function, though: it prevents
commands like:
% cat file1 file2 >> file2
from creating infinitely long files.