使用 tee 重定向文件描述符3

4

几个月前我写了这个脚本,现在重新阅读时,我无法解释我所写的这行代码的意思:

sudo rsync -xPRSaz --rsync-path='sudo rsync' maeve@macbook:/ macbook/ 3>&1 1>&2 2>&3 | tee macbook.log

我无法找到任何关于sudorsynctee文件描述符3的特殊处理。根据当前的重定向情况,我猜测情况如下:
now fd points to old fd
     0    -->         0
     1    -->         2
     2    -->         1
     3    -->         1
  • 这些重定向是应用于sudo还是rsync,以及有什么目的?
  • 文件描述符3是否被保持未关闭或以任何“不良”方式挂起?
2个回答

1
请注意,悬空的文件描述符 3 可以通过 3>&- 关闭。以下为包含该内容的完整行:
sudo rsync -xPRSaz --rsync-path='sudo rsync' maeve@macbook:/ macbook/ 3>&1 1>&2 \
2>&3 3>&- | tee macbook.log

1

你的猜测是正确的。交换标准输出和标准错误是一个相当巧妙的技巧。回答你的问题:

  • 这些重定向被 shell 捕获,因此它们适用于管道的那一部分(即 sudo)。sudo 进程本身将检测所有参数并将它们传递给其子命令 (rsync),但在此之前已经捕获并处理了重定向: sudo 从未看到它们。
  • 文件句柄 3 不会被悬挂。当进程结束时,它将被关闭。

在sudo执行之前关闭fd 3是必要的或可能的吗?我听说过一些程序可以通过这种方式传递打开的流。 - Matt Joiner
通常情况下是不必要的,因为进程不应该关心已经打开的文件描述符。在bash中有一种方法可以“移动”文件描述符(而不是复制它),这会关闭原始文件描述符。所以你可能可以使用这个方法来关闭文件句柄3。我从未尝试过(因为我从未有过这个需求),但是请在bash的手册中搜索“移动文件描述符”。 - paxdiablo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接