Can anyone help me understand this seemingly odd behavior of how the shell parses the redirects..?$ cat > test.txtLine 1Line 2$ ls -i dummy.txt dummy2.txtls: dummy.txt: No such file or directoryls: dummy2.txt: No such file or directory$ $ cat test.txt > dummy.txt > dummy2.txt$ cat dummy2.txtLine 1Line 2$ cat dummy.txt$Interesting! I would have expected the output from cat test.txt to be redirected into dummy.txt and then the shell would read dummy.txt as the input for dummy2.txt. But somehow the shell parses it differently... So how does the content of test.txt be taken as the input for dummy2.txt, by bypassing dummy.txt altogether?Note:Same result in bash and ksh..
What makes the shell interpret these redirects as follows?
shell script;io redirection
It's important to know that your shell is not redirecting the output, but the file descriptors. Every process on a POSIX-compatible operating system has 3 I/O streams: STDIN, STDOUT, and STDERR. The > redirection redirects the file descriptor for the STDOUT stream. So what the shell sees as it parses this line is:cat test.txt - Ok, I'll run the program cat and give it the argument test.txt> dummy.txt - Oh, now I'll take the STDOUT descriptor of the cat process and connect it to this file called dummy.txt. I don't care if anything was there before, I'll create the file and truncate it to zero.> dummy2.txt - Oh, now I'll take the STDOUT descriptor of the cat process (that I previously connected to dummy.txt) and connect it to a different new file. I can't do both things, because you're redirecting, not duping the file descriptors.This is why this command:find / 2>&1 >/dev/nullresults in error output on STDOUT, and no regular (STDOUT) output, but this one:find / >/dev/null 2>&1results in no output at all. In the first case, we put STDERR on a copy (dup) of STDOUT, then put the old STDOUT in the trash. In the second, we first put STDOUT in the trash, then copy it (still pointed to /dev/null) and put STDERR there, too.