使用tar打包提取子目录时如何保留正确的所有者权限?
解决tar打包子目录后提取时父目录权限丢失的问题
我明白你的问题了——你打包了a/b目录,但用root提取后,自动创建的c/a目录权限变成了root所有,而不是原foo用户的权限。这是因为你打包的时候只把a/b放进了归档,a目录本身的元数据(包括权限、属主)并没有被加入归档,所以tar提取时只能按默认规则新建a目录,root用户新建的目录自然就是root属主了。
解决方法核心:让归档包含父目录a的信息,分两步操作:
1. 修改打包命令,添加--parents参数
这个参数会让tar保留完整的目录路径,把所有父目录的元数据也打包进去。修改后的打包命令:
tar cf a.tar --parents a/b
现在你用tar tvf a.tar查看归档,就能看到里面不仅有a/b/和a/b/f2,还有a/的条目,包含它原有的权限和属主信息。
2. 提取时保留-p参数(你已经在用了)
提取命令保持不变,确保用-p(或完整写法--preserve-permissions)来保留文件和目录的权限:
sudo tar -C c -xpf a.tar
这样提取出来的c/a目录就会和原始的a目录权限、属主完全一致了。
验证效果:
打包后查看归档内容:
tar tvf a.tar # 会看到类似这样的条目: # drwxr-xr-x foo/op 0 2018-05-11 10:33 a/ # drwxr-xr-x foo/op 0 2018-05-11 10:33 a/b/ # -rw-r--r-- foo/op 0 2018-05-11 10:33 a/b/f2
提取后再用find c -ls查看,c/a的属主就会是foo/op,和你预期的结果完全匹配。
另外还有一种替代方法:打包时先添加a目录(不递归),再追加a/b的内容,命令如下:
tar cf a.tar a --no-recursion && tar rf a.tar a/b
效果和--parents一致,但--parents写法更简洁直观。
内容的提问来源于stack exchange,提问作者Daniel YC Lin




