/proc 和 /proc/(带有尾部斜杠)之间有什么区别?

/proc 和 /proc/(带有尾部斜杠)之间有什么区别?

我尝试使用tar备份我的文件。使用 时--exclude=/proc/,存档包含 /proc 下的文件,而使用 时--exclude=/proc则不包含。是什么导致了这种差异?

PS 我使用的shell是Bash。

答案1

对于目录而言,使用尾部斜杠与不使用尾部斜杠实际上没有太大区别,除了符号链接处理。请参阅开放群组基础规范,4.11 路径名解析(另见这个答案在 Unix SE 上)。

就 GNU tar 而言:--exclude正如您所注意到的,模式中的尾部斜杠根本无法处理。如果有人要指出某事的话,这种差异只是由其特定的源代码造成的 :-)。请参阅这个问题在 Server Fault SE 上(尽管它没有提供太多细节 - 它只是陈述事实)。请参阅此邮件主题了解一些相关信息。在这段话中也许能找到一些线索(尽管我不太确定该如何理解):

Otto Moerbeek 写道:

这是一段代码相关的:

            /*
             * Some programs that create ustar archives append a '/'
             * to the pathname for directories. This clearly violates
             * ustar specs, but we will silently strip it off anyway. 
             */
            if (arcn-> name[arcn-> nlen - 1] == '/')
                    arcn-> name[--arcn-> nlen] = '\0';

正如您使用 hexdump -C 查看 gtar 创建的档案时所看到的,gtar 就是这样一个程序。我不想仅仅为了适应不符合要求的程序而改变 tar。

答案2

通常,这取决于程序的惯例。对于 (GNU),tar这有点不一致,因为尾随的 / 不会改变包括目录。该行为部分解释这里模式和名称按原样使用“。Excludes 可以匹配名称的任何部分(除非您使用--anchor)。

文档并未清楚说明其中是否存在差异,或者为什么存在差异。

从内部来看,排除中尾随的 / 不匹配的原因是tar使用opendir(3),readdir(3)fnmatch(3)--opendir()接受/目录尾随,readdir()不在目录名称上加斜杠,并且fnmatch()只匹配模式而不考虑现有文件或规范化。具体来说,fnmatch("proc/","proc",0)返回 1(无匹配)。

比较一下rsync目录名尾随 / 的区别,它们有非常明显(并且有据可查)的区别。

一个相关的问题是,有时你想备份一个目录,因为它是挂载点,尽管您不需要其内容。目的是让您的备份可以包含所有必需的挂载点 ( /dev proc /sys),因此通常您需要执行以下操作:

tar --exclude=/proc/* --exclude=/sys/* --exclude=/dev/* [...]

相关内容