Before the shell executes the cat
command on the command line, it handles any redirections. Redirections include redirecting input or output using <
(stdin, read-only), <>
(stdin, read+write), >
(stdout, write-only) and >>
(stdout, write-only, appending output), but also <<word
(here-documents) and <<<'...'
(in some shells, "here-strings"). These redirection operators should occur unquoted to have the effect of redirecting input or output, and you can prepend a number to specify which file descriptor to redirect instead of the default (stdin (0) or stdout (1) depending on the operator).
There are two redirections in the command that you show:
>file1
This will make the command's standard output go to file1
.
<file2
This will make the command's standard input come from file2
.
The fact that these redirections are placed in a wonky location on the command line doesn't matter.
$ cat <file2 >file1
is the same as
$ <file2 cat >file1
which is the same as
$ <file2 >file1 cat
etc.¹
Note that the cat
utility in all of these instances is executed without any command line arguments. The redirections are not operands to the cat
command, they are instructions to the shell to set up redirections into and out of the command (connecting its standard input and output to files). The shell sets up the redirections before invoking the command.
The difference between cat file
and cat <file
(or, if you will, <file cat
) is that in the first case, the cat
utility itself is opening the file, which is given as an operand on the command line, for reading, while in the second case, the shell will open the file and connect cat
's input stream to it². In the second case, cat
will notice it wasn't given a file operand and will automatically switch to reading from its standard input. This is a feature of cat
, and of some other utilities, not something that all utilities do.
cat
will also read from its standard input if it's given the operand -
. Again, this is special only to cat
and to some other utilities (i.e. nothing that the shell does). To use cat
on a file in the current directory whose name is -
, add a path to the filename, such as ./-
.
¹ The order of the redirections is still important under some circumstances; With cat <file2 >file1
, for example, file1
will not be truncated if file2
is inaccessible (the redirections are parsed from left to right). The relative placement of the word cat
is however still arbitrary and won't influence this.
² See also the question "https://unix.stackexchange.com/questions/325706/cat-gives-different-error-when-opening-non-existing-file/".
The fact that the shell sets up the redirections before even executing the command on the command line is why things like these fail and you end up with an empty output file:
$ sort file >file
Here, the shell will truncate (empty) the file file
before executing sort file
and connecting sort
's standard output to the file. The sort
utility will then open file
and sort its contents (which is nothing). The result (nothing) is passed through the standard output stream to file
.
The remedy in this particular case (for sorting a file "in-place") is
$ sort -o file file
or
$ sort file >file.sorted && mv file.sorted file
or, to ensure that the original file is not deleted (to preserve certain file meta-data),
$ cp file file.unsorted && sort file.unsorted >file && rm -f file.unsorted
which is more or less what sort
does when using the -o
file to specify the output file name.
Just to back up the statement that the redirections may precede the actual name of the utility on the command line (my emphasis):
A "simple command" is a sequence of optional variable assignments and redirections, in any sequence, optionally followed by words and redirections, terminated by a control operator. [ref: POSIX Shell Command Language 2.9.1 Simple Commands]
And also about the redirection not being part of the operands of the utility:
The optional number, redirection operator, and word shall not appear in the arguments provided to the command to be executed (if any). [ref: POSIX Shell Command Language 2.7 Redirection]