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)
) 已经打开,则可能会关闭它(这不会对您的父进程执行任何操作,因为这发生在fork
ed 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 步骤,而是直接转至dup2
ing 匹配的文件描述符(即 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 将创建新的文件描述符并将其复制到您正在重定向的文件描述符。