man bash
在重定向时会这样说:
请注意,重定向的顺序很重要。
ls > dirlist 2>&1
将标准输出和标准错误都定向到文件dirlist,而命令
ls 2>&1 > dirlist
仅将标准输出定向到文件dirlist,因为在将标准输出重定向到dirlist之前,已从标准输出复制了标准错误。
我真的不懂那部分:
在将标准输出重定向到dirlist之前,从标准输出中复制了标准错误。
从我的Angular 来看,>
只是意味着重定向,就像ls > dirlist
将ls
的输出重定向到文件dirlist
。
所以2>&1
应该将stderr重定向到stdout,然后stdout应该被重定向到dirlist
(> dirlist
)。
“从流B复制流A”有什么用?
2条答案
按热度按时间hmmo2u0o1#
Shell重定向实际上只是调用系统调用
dup2()
。int dup2(int oldfd, int newfd);
dup()系统调用分配一个新的文件描述符,该描述符引用与描述符oldfd相同的打开文件描述。
这实际上并不是在做“重定向流”之类的事情--相反,它更改了打开文件的表,使表中某个位置的文件句柄可以从表中的另一个位置指向。
那么,让我们看看第一个例子,
ls > dirlist 2>&1
open(2)
打开文件dirlist
。dup2()
用于将open()
创建的文件句柄复制到FD 1(>
的默认值),并关闭动态创建的句柄。dup2()
用于将FD 1复制到FD 2。...最终结果:FD 1和FD 2都指向
dirlist
。现在,我们来看下一个示例
ls 2>&1 >dirlist
dup2()
用于将之前在FD 1打开的内容复制到FD 2open()
用于打开文件dirlist
dup2()
用于将dirlist上的句柄复制到FD 1,并关闭动态创建的句柄。...最终结果:FD 2现在指向FD 1的先前值,并且FD 1现在指向
dirlist
。ffscu2ro2#
您的手册与GNU网站上提供的手册略有不同,但请查看复制文件描述符:
重定向操作符[n]〈&word用于复制输入文件描述符。如果word扩展到一个或多个数字,则由n表示的文件描述符将成为该文件描述符的副本...操作符[n]〉&word类似地用于复制输出文件描述符。
所以当你写
2>&1
的时候,你是说你想让文件描述符2成为文件描述符1的一个副本。它并不是真的连接到文件描述符1,它只是指向同一个地方。因为它只是一个副本,对文件描述符1的修改不会自动应用到文件描述符2。这就是为什么顺序很重要。