In numerouse places, I've found people suggesting that you can swap stderr with stdout as follows:

command 3>&2 2>&1 1>&3

This looks backwards to me. If we send 3 to 2 and then immediately send 2 to 1 (which now would appear to be sending both 3 and 2 to 1). I think there's something basic I don't understand about IO redirection, but I can't find anything which clarifies it.

有帮助吗?

解决方案

You will find a detailed explanation at http://www.catonmat.net/blog/bash-one-liners-explained-part-three/ , section 21:

$ command 3>&1 1>&2 2>&3 Here we first duplicate file descriptor 3 to be a copy of stdout. Then we duplicate stdout to be a copy of stderr, and finally we duplicate stderr to be a copy of file descriptor 3, which is stdout. As a result we've swapped stdout and stderr.

There is more detail, and pictures, at the link given. The key insight is:

3>&1 means "3 points to where 1 is pointing". Then 1>&2 says "now 1 points to where 2 is pointing" (1 now points to stream 2, but 3 doesn't follow...), and finally 2>&3 says "now 2 points to where 3 is pointing (which is stream 1).

Graphically (but see link - it's much better than my ascii-art):

0 --> /dev/tty0
1 --> /dev/tty1
2 --> /dev/tty2

After 3>&1:

0 --> /dev/tty0
1 --> /dev/tty1
2 --> /dev/tty2
3 --> /dev/tty1

After 1>&2:

0 --> /dev/tty0
1 --> /dev/tty2
2 --> /dev/tty2
3 --> /dev/tty1

After 2>&3:

0 --> /dev/tty0
1 --> /dev/tty2
2 --> /dev/tty1
3 --> /dev/tty1

As you can see, 1 and 2 have been swapped. The same link recommends closing temporary stream 3 with 3>&-

其他提示

Huh, I've never seen that .... anyway ...it seems that is essentially saying firstly ... send 3 to the address of 2 .... then send two to the address of 1 .... then send one to the address of 3...which from the first step, we know is the original address of two ... so you've swapped them .... haven't tested that out myself though....

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top