tar --exclude 标志如果我在路径末尾添加'/'则不排除目录

tar --exclude flag not excluding the directory if I add the '/' at the end of the path

如果我使用这个命令:

sudo tar -zcvpf exclusion.tar.gz mybkup/ --exclude=mybkup/etc/ssh/

然后,如果我尝试查看 ssh 目录是否包含在 tarball 内容中,我发现实际上包含了:

[user@smashingx1 ~]$ tar -tvzf exclusion.tar.gz | grep ssh
lrwxrwxrwx user/user         0 2016-11-30 04:26 mybkup/etc/systemd/system/multi-user.target.wants/sshd.service -> /usr/lib/systemd/system/sshd.service
-rw-r----- user/user       506 2016-11-30 04:26 mybkup/etc/sysconfig/sshd
-rw-r--r-- user/user      5996 2016-11-30 04:26 mybkup/etc/xdg/autostart/gnome-keyring-ssh.desktop
drwxr-xr-x user/user         0 2016-11-30 04:26 mybkup/etc/ssh/
-rw-r--r-- user/user    242153 2016-11-30 04:26 mybkup/etc/ssh/moduli
-rw-r--r-- user/user      2208 2016-11-30 04:26 mybkup/etc/ssh/ssh_config
-rw-r--r-- user/user       382 2016-11-30 04:26 mybkup/etc/ssh/ssh_host_rsa_key.pub
-rw-r--r-- user/user       162 2016-11-30 04:26 mybkup/etc/ssh/ssh_host_ecdsa_key.pub
-rw-r--r-- user/user      4760 2016-11-30 04:26 mybkup/etc/ssh/sshd_config
-rw-r--r-- user/user        82 2016-11-30 04:26 mybkup/etc/ssh/ssh_host_ed25519_key.pub
-rw-r----- user/user      1675 2016-11-30 04:26 mybkup/etc/ssh/ssh_host_rsa_key
-rw-r----- user/user       227 2016-11-30 04:26 mybkup/etc/ssh/ssh_host_ecdsa_key
-rw------- user/user      4361 2016-11-30 04:26 mybkup/etc/ssh/sshd_config.rpmnew
-rw-r----- user/user       387 2016-11-30 04:26 mybkup/etc/ssh/ssh_host_ed25519_key
-rw-r--r-- user/user      8730 2016-11-30 04:26 mybkup/etc/selinux/targeted/modules/active/modules/rssh.pp
-rw-r--r-- user/user     18774 2016-11-30 04:26 mybkup/etc/selinux/targeted/modules/active/modules/ssh.pp
-rw-r--r-- user/user       904 2016-11-30 04:26 mybkup/etc/pam.d/sshd

但如果我不在目录路径末尾添加最后一个“/”,现在它会排除目录:

sudo tar -zcvpf exclusion.tar.gz mybkup/ --exclude=mybkup/etc/ssh

tar -tvzf exclusion.tar.gz | grep ssh

lrwxrwxrwx user/user         0 2016-11-30 04:26 mybkup/etc/systemd/system/multi-user.target.wants/sshd.service -> /usr/lib/systemd/system/sshd.service
-rw-r----- user/user       506 2016-11-30 04:26 mybkup/etc/sysconfig/sshd
-rw-r--r-- user/user      5996 2016-11-30 04:26 mybkup/etc/xdg/autostart/gnome-keyring-ssh.desktop
-rw-r--r-- user/user      8730 2016-11-30 04:26 mybkup/etc/selinux/targeted/modules/active/modules/rssh.pp
-rw-r--r-- user/user     18774 2016-11-30 04:26 mybkup/etc/selinux/targeted/modules/active/modules/ssh.pp
-rw-r--r-- user/user       904 2016-11-30 04:26 mybkup/etc/pam.d/sshd

我很困惑,因为我认为通过指示 tar 排除目录,它会排除目录及其内容,但显然不是这样,有人可以解释一下吗?

--排除=模式

排除文件,以模式给出

当您使用 --exclude=mybackup/etc/ssh/ tar 时,没有得到任何精确匹配的模式。并且当您使用 --exclude=mybackup/etc/ssh tar 时获得模式的完全匹配。

首先,快速提示。您可以更轻松地测试行为,而无需实际创建 tar 文件,如下所示:

tar c mybkup/ --exclude=mybkup/etc/ssh/ | tar t

希望你能欣赏其中的美

排除模式定义非常原始。 遗憾的是,man tar 没有解释任何有关 "PATTERN" 应该如何编写以及如何解释的内容。

根据一些观察,我得出以下推理。 在您的示例中, mybkup/etc/ssh/ 未被排除,因为它既不是文件也不是目录。虽然 mybkup/etc/ssh 是目录,但 mybkup/etc/ssh/ 不是。换句话说,尾随 / 不是目录名称的一部分,因此它不被视为目录,因此只是被忽略,而不是被排除。

恐怕就是这样。这是一个如此原始的功能。

Shell glob 没问题。例如,给定您的文件,如果您这样做:

tar c mybkup --exclude='mybkup/etc/sy*' | tar t

它将排除 mybkup/etc/systemdmybkup/etc/sysconfig 目录及其内容。 (请注意,引用 mybkup/etc/sy* 很重要,这样 tar 将解释 * 而不是 shell。)