![文件描述符打开一次但关闭多次;为什么会有差异?](https://linux22.com/image/1587410/%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E7%AC%A6%E6%89%93%E5%BC%80%E4%B8%80%E6%AC%A1%E4%BD%86%E5%85%B3%E9%97%AD%E5%A4%9A%E6%AC%A1%EF%BC%9B%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BC%9A%E6%9C%89%E5%B7%AE%E5%BC%82%EF%BC%9F.png)
我尝试使用进程替换并遇到以下示例:
exec 3>&1
tar cf /dev/fd/4 $directory_name 4>&1 >&3 3>&- | bzip2 -c > file.tar.bz2 3>&-
exec 3>&-
根据我的理解,这意味着以下内容:
创建文件描述符
3
并将其附加到标准输出。tar
将压缩 定义的目录中的文件,$directory_name
并且压缩文件在内部由文件描述符表示4
。文件描述符
4
附加到标准输出。stdout 附加到文件描述符
3
并且文件描述符3
已关闭。
但是bzip2
文件描述符再次关闭,最后一行exec
命令也关闭了描述符3
。我迷茫了,为什么同一个文件描述符被关闭了3次?
答案1
这些是不同的描述符。请参阅这个好答案。 它说:
[子进程] 继承了文件描述符的副本。因此,关闭子进程中的描述符将关闭子进程的描述符,但不会关闭父进程的描述符,反之亦然。
在类似的情况下,tar cf /dev/fd/4 $directory_name 4>&1 >&3 3>&-
重定向在启动之前由 shell 处理tar
,但原理是一样的:这些描述符不是主 shell 的描述符。tar
启动时(严格地说:当 shell 的副本最终执行到时tar
),它是 /dev/fd/*
链接已经准备好,并且没有/dev/fd/3
。
以同样的方式bzip2
发现它自己的描述符已准备好。它们可能与其他进程的描述符链接到相同的文件,但它们是独立的实体。
请记住,每个进程在 中都看到自己的描述符/dev/fd/
,这是一个有用的技巧。如果您考虑/proc/<PID>/fd/
目录,那么每个 PID 的描述符就会变得更加清晰。
最后exec 3>&-
关闭主 shell 的描述符。这是另一个独立的实体。