&1 refers to file descriptor 1. a>&b calls dup2(2) with oldfd=b and newfd=a. So ordering matters. STDOUT starts out attached to fd=1, but if you dup something else to fd=1, the association "fd 1 is STDOUT" is forgotten.
And that's exactly what usually happens; we replace fd 1 with one open to /dev/null, and then when we say 2>&1, that means to replace fd 2 (stderr) with whatever's at fd 1 (now /dev/null). When you write "command 2>&1 >/dev/null" that means something else, it means "send fd 2's output to what's currently at fd 1 (stdout)", and then "send what's currently at fd 1 to /dev/null". In other words, the source of a redirection is "by reference", but the destination of a redirection is "by value". If that makes any sense...
Think of it as saying "take fd 2 (stderr) and send it to the same place fd 1 is going now" So:
$ command >file.txt 2>&1
first redirects fd=1 to file.txt and then has fd=2 go the same place. Where:
$ command 2>&1 >file.txt
first has fd=2 go the original place stdout was and then redirect fd=1 only to file.txt. Usually not what you want. If you really wanted file.txt to get only the stdout while simultaneously sending what used to be stderr to stdout I think you'd have to use another file descriptor like:
$ command 3>&1 >file.txt 2>&3
That is, save the original stdout as fd=3, redirect stdout, then make stderr go the same place fd=3 is going.
I think this[1] is probably what you're looking for. If I'm understainding you correctly, the 2nd example will have mapped 2/stderr to &1 (stdout), before pointing stdout to the file, so you end up with both in the file.
Siblings have already responded to this well, so I'll just add an example:
$ ls x
ls: cannot access x: No such file or directory
$ ls x >/dev/null 2>&1
$ ls x 2>&1 >/dev/null
ls: cannot access x: No such file or directory
The first command shows us trying to list a non-existent file, raising an error. The second sends stderr to stdout before sending stdout to null, suppressing all output. The third sends the error to stdout; any output on stdout would have been suppressed (can you come up with a way to verify this?)
Your second example puts stderr into the old stdout, then makes a new stdout go into the file. You have to redirect the files in the proper sequence to get the desired behavior. It is quirky if you don't expect it.
I know it works, but this reads to me: command > file.txt 2>&1 "write the output of command to file.txt and then map the error output to stdout"
It makes so much more sense to write: command 2>&1 > file.txt
There is clearly something in my brain that is confused about how redirection works.