在 / 中运行 tar 时,如何排除“/sbin”,同时不排除“/usr/sbin”?
一些细节:普遍认为tar --exclude=dir
仅排除从 tar 当前工作目录中看到的“dir”及其子文件夹。
我没有找到任何文件支持这个观点,事实上我发现它是错误的。我正在使用古老的 SuSE、一些 CentOS 和 Debian(从 Lenny 到 Jessie)进行测试:tar --exclude=dir
排除“dir”无论在哪里找到了!
概念验证:
cd /tmp
mkdir -p dira/dirb/{a,b,c,d,e}
mkdir -p dirc/dira/{a,b,c,d,e}
tar c dir? | tar t
您将在创建的 tar“文件”中看到刚刚创建的每个目录。没关系。但与:
tar c dir? --exclude=dira/* | tar t
输出是:
dira/
dirc/
dirc/dira/
排除目录本身而不是其内容也是同样的:
tar c dir? --exclude=dira | tar t
给出:
dirc/
那不是我想要的!我想排除“dira/”,但不排除“dira/" 当 dira 本身是其他目录的子文件夹时。
将一些标记文件放入“dira”会有所帮助,但有时您无法做到这一点,例如,如果备份用户没有对排除目录的写权限,或者如果目录不更改很重要......
答案1
如果您使用 gnu tar,这里有一份内容广泛的手册这里讨论该--anchored
选项,以及排除和包含的全局模式有何不同。你可以试试:
tar c dir? --anchored --exclude=dira | tar t
答案2
不幸的是,tar
事实并非如此;它认为所有的文件名(包括子目录或父目录),并认为部分匹配就可以了。你想做的事是不可能的只是柏油。
不过幸运的是,您使用的是 UNIX 系统,因此您拥有整个工具箱,而不仅仅是单个命令。你可以按照这些思路做一些事情:
find . -print | grep -v '^\./dira' | xargs -d '\n' tar cf ../output.tar
第一个打印当前目录中的所有文件名;第二个通过在文件名上使用正则表达式来过滤掉您不需要的内容。该正则表达式中的字符^
确保匹配仅有的对于以下文件有效开始与正则表达式的其余部分(即您的dira
目录及其任何文件或子目录)。管道中的最后一个命令读取前两个命令的输出,并将其转换为 tar 的命令行,从而为 tar 提供要添加到存档中的文件列表。
答案3
为什么在尝试仅排除 /sbin 时看到 /usr/sbin 被排除:(
man tar
http://linux.die.net/man/1/tar)显示:
--exclude=PATTERN
exclude files, given as a PATTERN
它不是 DIR,而是 PATTERN,并且 /sbin 与 /usr/sbin 匹配。
您可以对此做什么,将 DIR 包含在排除的 DIR 中:
首先 tar up / 并排除 /sbin (也排除 /usr/sbin),并将输出发送到文件 archive.tar,然后使用 APPEND 选项将 /usr/sbin 附加到文件 archive.tar :
tar -cf archive.tar / --exclude=/sbin #### Partial Contents
tar -Af archive.tar /usr/sbin #### Contains everything you want