Robert Latest <
bobl...@yahoo.com>:
>I must say I understand very little of the redirection chapter in
>"man bash".
That's because the bash manual page purpose is not to teach the unix
file descriptor redirection mechanism. The bash manual page assumes
that the reader already is familiar with the unix file descriptors
and knows what “redirection” of those file descriptors is.
So, here is a very short introduction to unix file descriptors:
For accessing files, the kernel maintains two data structures: a
system-wide table (or array) of opened files, and a per-process
(i. e. each process has one of its own) table (or array) of file
descriptors. When a process asks the kernel to open a file, for
example by invoking the “open()” system service, the kernel picks an
unused entry of the process' table of file descriptors. This entry
will be identified by its position (or index) in that file
descriptor table: a small number (0, 1, 2, …), a. k. a. the file
descriptor number.
Then the kernel picks an unused entry of the system-wide table of
open files and records a reference to (for example: the position in
the system‐wide open‐files table) that entry in the allocated entry
of the process' table of file descriptors.
In the allocated entry of the system-wide table of open files, the
kernel records, which file is to be accessed, the access mode (that
is, whether the file is opened for reading or for writing, if
writing will overwrite the file or append to it, etc.), the current
access position in the opened file, and, how many file descriptor
table entries are associated with this entry of the system-wide
table of open files (in this case: 1).
Finally, the kernel returns the index of the allocated entry of the
process' file descriptor table to the process. In the bash manual
page that index is known as file descriptor number.
For example, the return value of the system call “open()” will
return such a number. See the manual page “open(2)”.
Note: The process can't (directly) tell the kernel, which entry
of the file descriptors table to use, when opening a file.
But there is a system service, which allows a process to tell the
kernel, which entry of the file descriptors table to use: “dup2()”.
See the manual page “dup2(2)”. The “dup()” and “dup2()” system
services essentially copy one entry of the process' file descriptor
table to another.
So, if you tell the shell to start a command by
command > output.txt
the shell will first open the file “output.txt” by means of the
system service “open”, which will (for example) return the file
descriptor number 42. Then the shell will tell the kernel by means
of the system service “dup2” to copy the contents of the entry #42
of the process' file descriptor table to the entry #1 in the same
table. Finally the shell will tell the kernel by means of the
system service “close” to release (i. e. empty) the entry #42.
The result of those three system service calls is, that the file
descriptor #1 will refer to the opened file “output.txt” (rather
than to the terminal): When the command writes data to its file
descriptor #1 (a. k. a. standard output), the data will arrive in
the file “output.txt”. That's why this sequence of system service
calls is often called redirection. But note: There is nothing like
redirection or forwarding involved in this mechanism. It's just the
effect of copying one file descriptor table entry to another.
Now, if the command is
> command > output.txt 2>&1
>
the shell first will do the same and then tell the kernel by means
of the system service “dup2” to copy the contents of the entry #1 to
the entry #2. Now two entries in the process' file descriptor
table – #1 and #2 – refer to the opened file “output.txt”.
On the other hand, look, what
> command 2>&1 > output.txt
>
would do: It would copy the entry #1 of the process' file
descriptor table to the entry #2 and then open the file
“output.txt”, thus getting the (hypothetical) entry #42, then copy
that entry #42 to the entry #1. Of course the entry #2 won't be a
copy of the entry #42 then, i. e. won't refer to the file
“output.txt”.
>It doesn't seem logical that a redirection specifier after the
>target file would influence what goes into that file.
You are fooled by the misnomer file descriptor redirection. Keep in
mind, that
2>&1
is essentially not much more than copying entry #1 to entry #2.
There is no forwarding involved like “if you want to write to the
file referred by the process' file descriptor table entry #2, look
up the file descriptor table entry #1 and use that instead”.
See also <
https://en.wikipedia.org/wiki/File_descriptor#top>.