我尝试使用进程替换并遇到以下示例:
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 的描述符。这是另一个独立的实体。