我可以使用额外的文件描述符来模拟 tee util 吗?

我可以使用额外的文件描述符来模拟 tee util 吗?

我还没有完全了解如何使用附加文件描述符。我怀疑您可以使用它们来模拟tee实用程序的功能,查看命令的输出,同时将其写入文件。我还怀疑这样做会帮助我更好地理解如何使用附加文件描述符......

到目前为止我的尝试,

date 3>&1 3>file

我的想法是,创造3作为重复1(标准输出)和重定向3写入file,因此我像往常一样将标准输出写入终端,并且3写入文件。

但这行不通。当我的时候cat file,它是空的。我哪里做错了?

答案1

重定向运算符变化输出的去向(或输入的来源)。3>&1意思是“让文件描述符3指向文件描述符1当前指向的任何地方”(即终端)。3>file意思是“使文件描述符3指向file”。在 fd 3 指向终端的短暂时间内没有发生任何事情,因此您不会得到任何终端输出。

为了在两个位置获取相同的数据,需要对数据进行复制。这是 的工作tee。对于它读取的每个字节,它都会输出该字节两次(如果给定一个文件参数,加上其标准输出)。

>&不要被有时称为重复的事实所困扰。它复制的是文件描述符3>&1将 fd 1 复制到 fd 3,这意味着发送到 fd 1 的数据和发送到 fd 3 的数据正在合并 — 它们都将发送到 fd 1 所指向的位置。

如果您喜欢图形解释,请参阅连接 STDOUT 和 STDIN 是什么意思?一个命令如何可以有多个输出?

无论如何,您的命令不会在文件描述符 3 上输出任何内容,因此重定向 fd 3 不会改变任何内容。该date命令写入其标准输出,即 fd 1,并且您没有重定向它。


Zsh 有一个功能叫做多操作系统这改变了输出重定向的含义。如果同一文件描述符上的同一命令有多个输出重定向,则第一个变化该描述符指向的位置,但后续的描述符复制将数据发送到指定的目标。例如,要获取文件中除了 stdout 指向的位置之外的输出,您可以使用

date >&1 >file

Zsh 正在做tee.请注意,重定向的顺序很重要 - date >file >&1将写入file两次,因为在评估运算符时,>&1标准输出date已经是file

答案2

不,因为它不会重复输出。要复制文件描述符,您还必须向它们输出两次。

尽管您可以使用循环来完成此操作,如下所示:

while read l
do
   echo "$l" >&3
   echo "$l" >&4
done

对于二进制数据,它会出现错误(零被分块,crlf-s 将转换为 lf)。

你的例子是这样做的:

  1. 打开 fd 3 到文件
  2. 将 fd 1 克隆到代替 fd 3(即它关闭你以前的 fd3 ,然后使 fd3 成为你以前的标准输出的“替代地址”)。

重定向本质上是一个克隆,用unix术语来说,它就像一个硬链接。使用3>&1命令后缀,您将拥有 fd 3 和 fd 1 指向同一实体(现在是file)。

如果您对 C 有一定的兴趣,我想检查一下 a man 3 dup2,这正是 fd 重定向的作用。

相关内容