shell bash:复制文件描述符

eufgjt7s  于 2022-11-16  发布在  Shell
关注(0)|答案(2)|浏览(181)

man bash在重定向时会这样说:
请注意,重定向的顺序很重要。

ls > dirlist 2>&1

将标准输出和标准错误都定向到文件dirlist,而命令

ls 2>&1 > dirlist

仅将标准输出定向到文件dirlist,因为在将标准输出重定向到dirlist之前,已从标准输出复制了标准错误。
我真的不懂那部分:
在将标准输出重定向到dirlist之前,从标准输出中复制了标准错误。
从我的Angular 来看,>只是意味着重定向,就像ls > dirlistls的输出重定向到文件dirlist
所以2>&1应该将stderr重定向到stdout,然后stdout应该被重定向到dirlist> dirlist)。
“从流B复制流A”有什么用?

hmmo2u0o

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 2
  • open()用于打开文件dirlist
  • dup2()用于将dirlist上的句柄复制到FD 1,并关闭动态创建的句柄。

...最终结果:FD 2现在指向FD 1的先前值,并且FD 1现在指向dirlist

ffscu2ro

ffscu2ro2#

您的手册与GNU网站上提供的手册略有不同,但请查看复制文件描述符:
重定向操作符[n]〈&word用于复制输入文件描述符。如果word扩展到一个或多个数字,则由n表示的文件描述符将成为该文件描述符的副本...操作符[n]〉&word类似地用于复制输出文件描述符。
所以当你写2>&1的时候,你是说你想让文件描述符2成为文件描述符1的一个副本。它并不是真的连接到文件描述符1,它只是指向同一个地方。因为它只是一个副本,对文件描述符1的修改不会自动应用到文件描述符2。这就是为什么顺序很重要。

相关问题