Also his example ` exec 5<> /tmp/lines.txt` fails with ambiguous redirect.
Also his example ` exec 5<> /tmp/lines.txt` fails with ambiguous redirect.
While stdin, out and err are files, they're not really the same thing as a /tmp/hello.txt type file you're thinking of. They're file system objects with special permissions. And while the idea is you'd use normal file read / writing APIs on them they're really more like FIFO buckets (technically it's a symlink to a file - for reasons that will make more sense shortly)
Take the example:
cat /tmp/hello.txt | grep world
(ignoring for the moment the "abuse of cat" for the sake of this example)So what would happen there `cat` would write to this bucket (the location of it varies from one OS to another) and another process in the pipe (eg `grep`) would read from that same bucket. But from the perspective of `cat` it's STDOUT and from the perspective of `grep` it's STDIN - even though they're the same file.
Things get a little more complicated when you start talking about redirection but essentially because each programs STDIN, STDOUT and STDERR file is actually just a symlink, when a program starts it's symlink points to another file instead of the normal one that would be next (or previous) in the pipeline. However this is all done automatically by the OS when you make the syscalls.
Things get even more complicated when you start talking about stuff that is read from or written to your terminal because they will be slightly different file system objects again but with a bit set to identify them as a pseudo-TTY. It's not really worth getting into the mechanics of it here. However ostensibly the principle is the same as the above.
edit: rewritten for clarity
Their example is $ cat /tmp/root_content.txt
And then in the picture the show that the `cat` program's stdout is `/tmp/root_content.txt`, which is incorrect according to your description. This would only be correct if it was then redirected or piped.
Because those streams are file system objects that use the same reading and writing APIs as regular files, it means you can also substitute them for regular files too. Which is what's happening in that specific example.
Essentially UNIX supports a whole array of special files that might behave slightly differently in the background but all can be interfaced with using the same principles as any regular file. It's quite a clever solution - albeit not without it's problems, kludges and mistakes too.