我在 bash 脚本中有一个非常简单的行,它成功执行(即生成文件_data.tar
),除了它不排除通过选项告知排除的子目录--exclude
:
/bin/tar -cf /home/_data.tar --exclude='/data/sub1/*' --exclude='/data/sub2/*' --exclude='/data/sub3/*' --exclude='/data/sub4/*' --exclude='/data/sub5/*' /data
相反,它会生成一个_data.tar
包含 /data 下所有内容的文件,包括我想要排除的子目录中的文件。
知道为什么吗?以及如何解决这个问题?
更新我根据下面第一个答案中提供的链接实现了我的观察(首先是顶级目录,最后排除后没有空格):
/bin/tar -cf /home/_data.tar /data --exclude='/data/sub1/*' --exclude='/data/sub2/*' --exclude='/data/sub3/*' --exclude='/data/sub4/*' --exclude='/data/sub5/*'
但这没有帮助。所有“排除”的子目录都出现在结果_data.tar
文件中。
这令人费解。无论这是当前 tar(GNU tar 1.23,在 CentOS 6.2、Linux 2.6.32 上)中的错误,还是 tar 对空格和其他容易错过的拼写错误的“极度敏感”,我都认为这是一个错误。目前。
这太可怕了:我尝试了下面建议的见解(无尾随/*
),但它在生产脚本中仍然不起作用:
/bin/tar -cf /home/_data.tar /data --exclude='/data/sub1' --exclude='/data/sub2' --exclude='/data/sub3' --exclude='/data/sub4'
除了引号和 2 个空格而不是 1 个空格之外,我看不出我尝试过的内容和 @Richard Perrin 尝试过的内容之间有任何区别。我将尝试这个(必须等待夜间脚本作为要支持的目录运行)向上是巨大的)并报告回来。
/bin/tar -cf /home/_data.tar /data --exclude=/data/sub1 --exclude=/data/sub2 --exclude=/data/sub3 --exclude=/data/sub4
我开始认为所有这些tar --exclude
敏感性都不是焦油,而是我环境中的某些东西,但那可能是什么?
有效!尝试的最后一个变体(没有单引号和单空格而不是--exclude
s 之间的双空格)测试了工作。奇怪但可以接受。
难以置信!事实证明,旧版本的tar
(1.15.1) 仅当顶级目录为最后的在命令行上。这与 1.23 版本的要求完全相反。供参考。
答案1
您的版本可能tar
要求--exclude
必须将选项放在命令的开头tar
。
看:https://stackoverflow.com/q/984204
tar --exclude='./folder' --exclude='./upload/folder2' \
-zcvf /backup/filename.tgz .
看:http://mandrivausers.org/index.php?/topic/8585-multiple-exclude-in-tar/
tar --exclude=<first> --exclude=<second> -cjf backupfile.bz2 /home/*
选择:
EXCLD='first second third'
tar -X <(for i in ${EXCLD}; do echo $i; done) -cjf backupfile.bz2 /home/*
另一个tar
命令提示来自这里:
tar cvfz myproject.tgz --exclude='path/dir_to_exclude1' \
--exclude='path/dir_to_exclude2' myproject
答案2
如果要排除整个目录,您的模式应该匹配该目录,而不是其中的文件。使用--exclude=/data/sub1
而不是--exclude='/data/sub1/*'
小心引用模式以保护它们免受 shell 扩展的影响。
请参阅此示例,最终调用时遇到问题:
$ for i in 0 1 2; do mkdir -p /tmp/data/sub$i; echo foo > /tmp/data/sub$i/foo; done
$ find /tmp/data
/tmp/data
/tmp/data/sub2
/tmp/data/sub2/foo
/tmp/data/sub0
/tmp/data/sub0/foo
/tmp/data/sub1
/tmp/data/sub1/foo
$ tar -zvcf /tmp/_data.tar /tmp/data --exclude='/tmp/data/sub[1-2]'
tar: Removing leading `/' from member names
/tmp/data/
/tmp/data/sub0/
/tmp/data/sub0/foo
$ tar -zvcf /tmp/_data.tar /tmp/data --exclude=/tmp/data/sub[1-2]
tar: Removing leading `/' from member names
/tmp/data/
/tmp/data/sub0/
/tmp/data/sub0/foo
$ echo tar -zvcf /tmp/_data.tar /tmp/data --exclude=/tmp/data/sub[1-2]
tar -zvcf /tmp/_data.tar /tmp/data --exclude=/tmp/data/sub[1-2]
$ tar -zvcf /tmp/_data.tar /tmp/data --exclude /tmp/data/sub[1-2]
tar: Removing leading `/' from member names
/tmp/data/
/tmp/data/sub2/
/tmp/data/sub2/foo
/tmp/data/sub0/
/tmp/data/sub0/foo
/tmp/data/sub2/
tar: Removing leading `/' from hard link targets
/tmp/data/sub2/foo
$ echo tar -zvcf /tmp/_data.tar /tmp/data --exclude /tmp/data/sub[1-2]
tar -zvcf /tmp/_data.tar /tmp/data --exclude /tmp/data/sub1 /tmp/data/sub2
答案3
要排除多个文件,请尝试
--exclude=/data/{sub1,sub2,sub3,sub4}
这将节省一些代码并减少头痛。这是一个全球解决方案,适用于所有类型的程序/选项。如果您还想在选择中包含父目录(在本例中为数据),则必须包含尾随逗号。例如:
umount /data/{sub1,sub2,}
答案4
此链接可能会有所帮助。 http://answers.google.com/answers/threadview/id/739467.html
非工作线和链接中的一些提示之间的两个直接区别:
- 所有排除都来了后顶级目录。
- 最后一个之后不能有任何空格
--exclude
。