Zip归档排除子目录语法解析:路径匹配疑问解答
核心原因:tar的排除模式匹配逻辑 + shell的隐藏文件glob规则
先明确你的场景:
- 当前工作目录是
temp(也就是你正处在/父目录/temp下) - 目标:打包整个
temp目录(让压缩包顶层就是temp),同时排除其中的.hidden子目录及其所有内容
为什么../temp/.hidden*无法生效?
这里有两个关键问题:
shell默认不匹配隐藏文件的glob:
bash等shell默认不会把*.hidden这类glob模式匹配到以.开头的隐藏文件/目录。所以当你写--exclude='../temp/.hidden*'时,shell找不到任何匹配的文件,会直接把字符串../temp/.hidden*原封不动传给tar。tar的排除模式认的是「打包根的相对路径」:
当你打包../temp时,tar会把这个目录当成打包根,压缩包内所有文件的路径都是相对于这个根的(比如.hidden、file.txt、subdir/note.md)。而../temp/.hidden*带了../temp/前缀,这是相对于你当前工作目录的路径,和tar内部的相对路径(.hidden)完全不匹配,所以tar根本识别不出这是要排除的目标,自然不会生效。
为什么../temp/*.hidden*(你说的简洁写法)能生效?
其实这里大概率是你混淆了写法——真正简洁且正确的写法应该是--exclude='.hidden*'或者--exclude='./.hidden*',而不是带../temp/前缀的版本。不过如果../temp/*.hidden*确实能工作,那可能是以下情况:
- 如果你开启了shell的
dotglob选项(允许glob匹配隐藏文件),../temp/.hidden*会被展开成../temp/.hidden,传给tar后只能排除目录本身,但管不了里面的内容;而../temp/*.hidden*(更可能是你笔误写成了这个,实际应该是.hidden*)是直接匹配tar内部所有以.hidden开头的路径,包括目录和里面的所有文件/子目录,一次性就排除了整个.hidden目录树。
给你一个正确的简洁命令示例
当前目录是temp时,直接用这个就可以实现需求:
tar -czf temp.tar.gz --exclude='.hidden*' ../temp
这个命令里的.hidden*是相对于打包根(../temp)的路径模式,tar会精准匹配所有以.hidden开头的条目,完美排除目标目录,同时压缩包顶层就是temp目录。
内容的提问来源于stack exchange,提问作者gcapes
相关产品推荐
相关产品推荐

