重定向中的文件描述符重复

重定向中的文件描述符重复

来自 GNU Bash 参考手册,第 3.6 节重定向:

Bash 在重定向中使用多个文件名时会专门处理这些文件名,如下表所述:

/dev/fd/fd

    如果FD是一个有效的整数,文件描述符FD是重复的。

/dev/stdin

    文件描述符 0 重复。

/dev/stdout

    文件描述符 1 重复。

/dev/stderr

    文件描述符 2 重复。

这里的“重复”是什么意思?你能举一些例子吗?

(以上内容摘自4.3版,最后更新于 2014 年 2 月 2 日,GNU Bash 参考手册,对于Bash,版本 4.3。)

答案1

重定向是通过以下方式实现的重复系统函数族。dup是缩写复制当你这样做时,例如:

3>&2

您将 ( dup2) filedescritor 2 复制到文件描述符 3 上,如果文件描述符 3 ( dup2(2,3)) 已经打开,则可能会关闭它(这不会对您的父进程执行任何操作,因为这发生在forked off 子进程中(如果没有的话(shell 上的重定向)在某些上下文中起作用),shell 会让它看起来好像确实如此))。

当你这样做时:

1<someFile

它将open someFile位于一个新的文件描述符上(这就是open系统调用通常所做的事情),然后将该dup2文件描述符放到 1 ( dup2(newfd,1)) 上。

复制的目标文件描述符在左侧始终不带“&”(可能有助于将重定向视为分配,而不会被/ /left=right令人困惑的方向性所混淆),并且右侧具有打开文件的文件名来自 ( 、、或然后确定应如何打开它 - 用于截断写入和可能的创建、用于追加和可能的创建或仅读取),或者,右侧有一个 & 号,后跟源文件描述符 (不受、、 或) 的影响。如果省略左侧,则隐含 for or和for 。<>>>>>><>>><1>>>0<

手册所说的是,如果列出的特殊 dev 文件之一取代了someFile,shell 将跳过open-on-a-new-fd 步骤,而是直接转至dup2ing 匹配的文件描述符(即 1 表示 /dev/ stdout 等)到目标(重定向左侧的文件描述符),所以

  • /dev/stdin 作为重定向源 (RHS) <=> &0
  • /dev/stdout 作为重定向源 (RHS) <=> &1
  • /dev/stderr 作为重定向源 (RHS) <=> &2
  • /dev/fd/$somefd 作为重定向源 (RHS) <=> &$somefd

答案2

文件描述符是指向内核全局文件表的指针(请参阅https://www.computerhope.com/jargon/f/file-descriptor.htm例如)。所以它有它的编号(充当它的标签或名称)和值(实际的指针)。当您将文件描述符复制到另一个文件描述符时,实际上是将指针值从源文件描述符复制到目标文件描述符,因此复制将源转化为目标。

所以声明:

当多个文件名用于 > 重定向时,Bash 会专门处理这些文件名,如下表所述。 [...]

/dev/粗壮

  File descriptor 1 is duplicated

意味着,当你这样做时“n>/dev/stdout”(重定向到 /dev/stdout 或将 /dev/stdout fd 复制到 n fd 中),bash 简单地复制 fd“1”。如果您要重定向到常规(非特殊文件),bash 将创建新的文件描述符并将其复制到您正在重定向的文件描述符。

相关内容