tar“--exclude-from”双星通配符

tar“--exclude-from”双星通配符

我在 Debian 8 系统上编写了一个备份脚本,它使用 tar 命令和“--exclude-from”来排除一些文件/目录。

这很好用,但今天我想排除一些共享相同路径模式的文件,例如/home/www-data/sites/<some_string>log.txt/home/www-data/sites/<one_or_two_directories>/vendor.

我尝试追加/home/www-data/sites/*log.txt到文件中,但 tar 失败并在 stderr 上输出以下错误:

tar: /home/www-data/sites/*log.txt: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

我在尝试使用*or时错过了什么**吗?

然后我读到了在 Unix 中,程序本身通常不解释通配符这意味着tar*也不会扩展它**

据我所知,我最后的手段是在调用之前使用 bash 扩展列表并将其附加到排除文件中(如果它尚不存在)tar。有更干净的方法吗?

编辑

这是脚本片段..

# ...
broot=$(dirname "${PWD}")
i="${PWD}/list.include"
x="${PWD}/list.exclude"
o="$broot/archive.tgz"
tar -zpcf $o -T $i -X $x
# ...

这是排除文件..

/etc/php5/fpm
/etc/nginx
/etc/mysql
/home/me/websites/*log.txt
/home/me/websites/**/vendor

目标是排除位于“网站”目录内的所有日志文件以及可在“网站”的任何子目录中找到的所有“供应商”目录。

答案1

shell 扩展参数中的通配符,因此大多数应用程序不需要执行任何通配符扩展。然而 tar 的排除列表支持通配符,恰好与传统 shell 支持的通配符匹配。请注意可能存在细微差异;例如 tar 无法区分***而 ksh、bash 和 zsh 可以。对于 tar,*可以匹配包括 在内的任何字符/,因此例如排除在层次结构的任何级别*/.svn调用的文件。您可以在与目录分隔符不匹配的情况下.svn使用。tar --no-wildcards-match-slash*

例如,/home/me/websites/*log.txt排除/home/me/websites/log.txt/home/me/websites/foo-log.txt/home/me/websites/subdir/log.txt。排除/home/me/websites/**/vendor排除/home/me/websites/one/vendor/home/me/websites/one/two/vendor但不排除/home/me/websites/vendor。使用该--no-wildcards-match-slash选项,/home/me/websites/*log.txt不排除/home/me/websites/subdir/log.txt/home/me/websites/**/vendor不排除/home/me/websites/one/two/vendor

tar … --exclude='/home/www-data/sites/*include' …/home/www-data/sites排除名称以 . 结尾的文件和目录include。你可能会在没有引号的情况下逃脱,但如果你这样写--exclude /home/www-data/sites/*include(因为这样 shell 会在tar看到通配符之前展开通配符)或者如果你使用的 shell 在不匹配的通配符上发出错误信号(例如默认的 zsh ),则不会。 并推荐- 配置)。

该选项--exclude-from需要文件名。该文件每行必须包含一个模式。不要混淆--exclude(后跟模式)和--exclude-from(后跟包含模式的文件名)。

答案2

您的命令可能被不正确地引用(这里快速检查是否按预期工作)。根据参考手册,GNU tar 识别 shell 通配符:

相关内容