在数字室中,我发现有人建议您可以用stdout交换stderr,如下所示:
命令3>&2 2>&1>&3
这反过来看。如果我们发送3到2,然后立即发送2到1(现在看起来是同时发送3和2到1)。我认为IO重定向有一些基本的我不理解的地方,但我找不到任何东西来澄清它
您可以在http://www.catonmat.net/blog/bash-one-liners-explained-part-three/,第21节:
$command 3>&1>&2 2>&3在这里,我们首先将文件描述符3复制到是stdout的副本。然后我们将stdout复制为stderr的副本,最后我们将stderr复制为文件描述符3的副本,即stdout。因此,我们交换了stdout和stderr。
在给出的链接中有更多细节和图片。关键见解是:
3>&1
的意思是"3点到1所指向的位置"。然后1>&2
说"现在1指向2所指向的位置"(1现在指向流2,但3没有跟随…),最后2>&3
说"现在2指向3所指向的地方(即流1)
图示(但请参阅链接-它比我的ascii艺术要好得多):
0 --> /dev/tty0
1 --> /dev/tty1
2 --> /dev/tty2
3>&1
:之后
0 --> /dev/tty0
1 --> /dev/tty1
2 --> /dev/tty2
3 --> /dev/tty1
1>&2
:之后
0 --> /dev/tty0
1 --> /dev/tty2
2 --> /dev/tty2
3 --> /dev/tty1
2>&3
:之后
0 --> /dev/tty0
1 --> /dev/tty2
2 --> /dev/tty1
3 --> /dev/tty1
如您所见,1
和2
已经交换。同一链接建议使用3>&-
关闭临时流3
啊,我从来没见过。。。。无论如何这似乎本质上是在说。。。将3发送到2…的地址。。。。然后将两个发送到1…的地址。。。。然后将一个发送到3的地址…从第一步开始,我们就知道这是两个的原始地址。。。所以你交换了它们。。。。但我自己还没有测试过。。。。
它之所以向后看,是因为它是向后看。
当您看到2>&1
时,它看起来像是在向stdout(1)发送stderr(2)。它似乎是这样工作的,程序写入stderr的数据到达stdin管道中的下一个程序。但它并不是这样实现的。该实现将stdout文件描述符(1)的内容分配给stderr文件描述符(2),这样,当程序写入stderr或stdout时,数据就会到达同一位置。
让我们发明一种替代的、虚构的语法。文件描述符是名称为stdin
、stdout
、stderr
、fd3
、fd4
等的变量,并且按照传统方式从右到左进行分配。
在我们的虚构语法中,stderr = stdout
对应于";向后";shell语法CCD_ 18。因为>
指向右边,所以看起来赋值指向右边,对吧?错误的这是一个从右到左的任务。
因此,令人困惑的、向后看的3>&2 2>&1 1>&3
通过一个临时变量变成了一个简单的交换:
fd3 = stderr
stderr = stdout
stdout = fd3
添加3>&-
以关闭临时类似于添加fd3 = null