我在我的 Debian 8 系统上编写了一个备份脚本,它使用带有“--exclude-from”的 tar 命令来排除一些文件/目录。
这很好用,但今天我想排除一些共享相同路径模式的文件,/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
Run Code Online (Sandbox Code Playgroud)
我错过尝试使用的东西时,*还是**?
然后我在 Unix 中读到,程序通常不会自己解释通配符,这意味着它*不会**被 tar扩展。
据我所知,我在这里的最后手段是在tar调用之前使用 bash 扩展列表并将其附加到排除文件中(如果它还没有)。有更干净的方法吗?
编辑
这是脚本片段..
# ...
broot=$(dirname "${PWD}")
i="${PWD}/list.include"
x="${PWD}/list.exclude"
o="$broot/archive.tgz"
tar -zpcf $o -T $i -X $x
# ...
Run Code Online (Sandbox Code Playgroud)
这里的丹斯是排除文件..
/etc/php5/fpm
/etc/nginx
/etc/mysql
/home/me/websites/*log.txt
/home/me/websites/**/vendor
Run Code Online (Sandbox Code Playgroud)
目标是排除位于“websites”目录中的所有日志文件,以及可以在“websites”的任何子目录中找到的所有“vendor”目录。
谢谢 !
Gil*_*il' 10
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/*includetar可以看到它们之前扩展通配符)或者如果您使用的外壳在不匹配的通配符上发出错误信号(例如默认情况下的 zsh - 和推荐——配置)。
该选项--exclude-from需要一个文件名。该文件必须每行包含一个模式。不要混淆--exclude(后跟模式)和--exclude-from(后跟包含模式的文件名)。