tar --exclude 不排除。为什么?

ate*_*iob 100 tar

我在成功执行的 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
Run Code Online (Sandbox Code Playgroud)

相反,它生成一个_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/*'
Run Code Online (Sandbox Code Playgroud)

但这没有帮助。所有“排除的”子目录都存在于结果_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'
Run Code Online (Sandbox Code Playgroud)

除了引号和 2 个空格而不是 1 个空格之外,我看不出我尝试过的和@Richard Perrin 尝试过的有任何区别。我要试试这个(必须等待每晚脚本作为要支持的目录运行) up 是巨大的)并报告。

/bin/tar -cf /home/_data.tar  /data --exclude=/data/sub1 --exclude=/data/sub2 --exclude=/data/sub3 --exclude=/data/sub4
Run Code Online (Sandbox Code Playgroud)

我开始认为所有这些tar --exclude敏感性都不是焦油而是我环境中的某些东西,但那会是什么?

有效!尝试的最后一个变体(在--excludes之间没有单引号和单空格而不是双空格)测试工作。奇怪但接受。

逆天!事实证明,旧版本的tar(1.15.1) 只会排除顶级目录是否位于命令行的最后。这与 1.23 版的要求完全相反。供参考。

小智 68

可能是您的版本tar要求必须将--exclude选项放在tar命令的开头。

参见:https : //stackoverflow.com/q/984204

tar --exclude='./folder' --exclude='./upload/folder2' \
    -zcvf /backup/filename.tgz .
Run Code Online (Sandbox Code Playgroud)

见:http : //mandrivausers.org/index.php?/topic/8585-multiple-exclude-in-tar/

tar --exclude=<first> --exclude=<second> -cjf backupfile.bz2 /home/*
Run Code Online (Sandbox Code Playgroud)

选择:

EXCLD='first second third'
tar -X <(for i in ${EXCLD}; do echo $i; done) -cjf backupfile.bz2 /home/*
Run Code Online (Sandbox Code Playgroud)

另一个tar命令提示来自这里

tar cvfz myproject.tgz --exclude='path/dir_to_exclude1' \
                       --exclude='path/dir_to_exclude2' myproject
Run Code Online (Sandbox Code Playgroud)

  • 我的版本 (1.29) 仅适用于 `-czf` 之前的 `--exclude`。 (3认同)

R P*_*rin 66

如果您想排除整个目录,您的模式应该匹配该目录,而不是其中的文件。使用--exclude=/data/sub1代替--exclude='/data/sub1/*'

引用模式时要小心,以保护它们免受外壳扩展。

请参阅此示例,最终调用时遇到问题:

$ 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
Run Code Online (Sandbox Code Playgroud)


小智 8

要排除多个文件,请尝试

--exclude=/data/{sub1,sub2,sub3,sub4}
Run Code Online (Sandbox Code Playgroud)

这将节省一些代码和头痛。这是一个全局解决方案,适用于所有类型的程序/选项。如果您还想在您的选择中包含父目录(在本例中为数据),则必须包含一个尾随逗号。例如:

umount /data/{sub1,sub2,}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢卷发。我发现很多人不知道它们,即使有多年的 unix 经验。`mv /very/very/very/very/long/path/to/a/file{,.bak}` (4认同)

小智 5

此链接可能会有所帮助。 http://answers.google.com/answers/threadview/id/739467.html

非工作行和链接中的一些提示之间的两个直接区别:

  1. 所有排除都顶级目录之后。
  2. 最后一个后不能有任何空格--exclude


小智 5

我使用的是 mac,发现排除不起作用,除非顶级文件夹是最后一个参数

工作命令示例:

tar czvf tar.tgz --exclude='Music' dir
Run Code Online (Sandbox Code Playgroud)

供参考:

$: tar --version
bsdtar 2.8.3 - libarchive 2.8.3
Run Code Online (Sandbox Code Playgroud)


小智 5

就我而言,它并没有因为其他原因而排除在外。

完整路径与相对路径。

exclude 和 directory 必须使用相同的路径格式(即都是完整路径或都是相对路径)

例子:

tar -cvf ctms-db-sync.tar --exclude='/home/mine/tmp/ctms-db-sync/sql' ctms-db-sync
Run Code Online (Sandbox Code Playgroud)

这将不起作用,因为 exclude 使用完整路径,而目标使用相对路径

tar -cvf ctms-db-sync.tar --exclude='/home/mine/tmp/ctms-db-sync/sql' /home/mine/tmp/ctms-db-sync
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为两者都使用完整路径

tar -cvf ctms-db-sync.tar --exclude='ctms-db-sync/sql' ctms-db-sync
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为两者都使用相对路径