TLDR;
Look at below two command lines.
$ non_exist_command 2>&1 > log.txt
$ non_exist_command > log.txt 2>&1
If you are super clear of the differences between the above two command lines, go away!
If not, read on.
Explanation
$ non_exist_command > log.txt 2>&1
In Bash, the IO redirection operators are processed one by one from left to right. Take the first command line as an example here. When shell starts a new process for this command line, at the very beginning, the file descriptor table is like below.
---------------------------------------------------
| file descriptor | the device pointed to |
---------------------------------------------------
| 0 | /dev/console |
---------------------------------------------------
| 1 | /dev/console |
---------------------------------------------------
| 2 | /dev/console |
---------------------------------------------------
After processing the first IO redirection, 2>&1, the table becomes
---------------------------------------------------
| file descriptor | the device pointed to |
---------------------------------------------------
| 0 | /dev/console |
---------------------------------------------------
| 1 | /dev/console |
---------------------------------------------------
| 2 | /dev/console |
---------------------------------------------------
You can see here, actually nothing changed. It's because the device refereced by fd=1 at this moment is /dev/console.
Then bash processes the second IO redirection, > log.txt.
---------------------------------------------------
| file descriptor | the device pointed to |
---------------------------------------------------
| 0 | /dev/console |
---------------------------------------------------
| 1 | ./log.txt |
---------------------------------------------------
| 2 | /dev/console |
---------------------------------------------------
$ non_exist_command > log.txt 2>&1
When shell starts a new process for this command line, at the very beginning, the file descriptor table is like below.
---------------------------------------------------
| file descriptor | the device pointed to |
---------------------------------------------------
| 0 | /dev/console |
---------------------------------------------------
| 1 | /dev/console |
---------------------------------------------------
| 2 | /dev/console |
---------------------------------------------------
After processing the first IO redirection, > log.txt, the table becomes
---------------------------------------------------
| file descriptor | the device pointed to |
---------------------------------------------------
| 0 | /dev/console |
---------------------------------------------------
| 1 | ./log.txt |
---------------------------------------------------
| 2 | /dev/console |
---------------------------------------------------
Then bash processes the second IO redirection, 2>&1. At this moment, fd=1 is referencing log.txt. So after 2>&1, fd=2 refreces log.txt as well.
---------------------------------------------------
| file descriptor | the device pointed to |
---------------------------------------------------
| 0 | /dev/console |
---------------------------------------------------
| 1 | ./log.txt |
---------------------------------------------------
| 2 | ./log.txt |
---------------------------------------------------
No comments:
Post a Comment