bash:文件描述符的重复



man bash在重定向时这样说:

注意重定向的顺序很重要。例如命令

ls > dirlist 2>&1

将标准输出和标准错误都指向文件目录列表,而命令

ls 2>&1 > dirlist

仅将标准输出定向到文件目录列表,因为标准在标准输出被重定向到目录列表。

我真的不明白这个部分:

在将标准输出重定向到目录列表之前,标准错误已从标准输出中复制。

从我的角度来看,>只是指重定向,就像ls > dirlistls的输出重定向到文件dirlist一样。

因此,2>&1应该将stderr重定向到stdout,然后将stdout重定向到dirlist(> dirlist(。然而,显然只有stdout被重定向到dirlist

这是怎么回事;从流B复制的流A";?

Shell重定向实际上只是调用系统调用dup2()。引用自https://man7.org/linux/man-pages/man2/dup.2.html--

int dup2(int oldfd, int newfd);

dup((系统调用分配一个新的文件描述符,该描述符引用与描述符oldfd相同的打开文件描述。

这实际上并没有像";重定向流"——相反,它改变了打开文件的表,使表中某个位置的文件句柄从表中的另一个位置指向。

所以,让我们看看您的第一个例子,ls > dirlist 2>&1

  • 使用open(2)打开文件dirlist
  • dup2()用于将open()创建的文件句柄复制到FD 1(>的默认值(,并关闭动态创建的句柄
  • CCD_ 18用于将FD 1复制到FD 2

。。。净结果:FD 1和FD 2都指向CCD_ 19。


现在,让我们看看您的下一个示例,ls 2>&1 >dirlist

  • dup2()用于将先前在FD 1打开的内容复制到FD 2
  • open()用于打开文件dirlist
  • dup2()用于将目录列表上的句柄复制到FD 1,并关闭动态创建的句柄

。。。净结果:FD 2现在指向FD 1的先前值,而FD 1现在指向dirlist

您的手册与GNU网站上的手册有点不同,但请参阅Duplicateing File Descriptors:

重定向运算符[n]<amp;word用于复制输入文件描述符。如果单词扩展到一个或多个数字,则由n表示的文件描述符将成为该文件描述符的副本。。。运算符[n]>amp;word类似地用于复制输出文件描述符。

因此,当您编写2>&1时,您表示希望文件描述符2成为文件描述符1的副本。它并没有真正连接到文件描述符1,它只是指向同一个地方。由于它只是一个副本,对文件描述符1的更改不会自动应用回文件描述符2。这就是为什么秩序很重要。

相关内容

  • 没有找到相关文章

最新更新