使用tar归档隐藏目录

28

tar 对一个名为 mydir 的目录进行归档时,会将隐藏文件和子目录也归档,但是在 mydir 目录内使用 * 通配符的 tar 命令则不会。这是已知的不一致性或缺陷吗?

编辑:额外信息。在 mydir 目录内使用带有 * 通配符的 tar 命令不会“看到”并归档该目录中立即级别下的隐藏文件和子目录。然而,在 mydir 目录的非隐藏子目录中,隐藏文件和子目录将被归档。换句话说,深入目录树中的隐藏对象将被归档。

7个回答

42

使用通配符将无法正常工作。如果您要指定包括隐藏文件在内的完整目录,则必须指定“。”(当前目录)。您可以执行以下操作:

tar -cvpzf test.tgz .

10
请注意不要把新的压缩文件放在你正在进行压缩的同一目录下,否则可能会出现恶性循环。 - Keith
15
tar cvpfz test.tgz --exclude=*.tgz . - H2ONaCl
7
把它放在别的地方就行了:tar czpf /var/tmp/mytar.tgz . - Keith
把它放在其他地方可能意味着需要使用sudo,这可能会导致在处理基于GUI的调度程序或crontab时需要额外的工作(你可能想避免这种情况)。 - H2ONaCl
1
但是你可以随时写入 /var/tmp。实际上,这就是我通常的做法。 - Keith
我在上面的评论中写了解决方案 tar cvpfz test.tgz --exclude=*.tgz .,因为它解决了不想打包新 tar 文件的问题,但我不建议这样做。我认为最好从外部调用 tar(即从父目录),这样你可以明确命名要打包的目录并避免使用 .(点)。这样做的好处是明确且避免需要使用 --exclude 选项。 - H2ONaCl

13
答案是通配符*由shell处理,不会扩展到以点开头的内容。另一个通配符?也不会扩展到以点开头的内容。感谢Keith指出这是由shell进行扩展,因此与tar无关。
如果使用shopt -s dotglob,则扩展将包括像.filename这样的内容。感谢Andy。
使用shopt -u dotglob关闭它。
切换dotglob选项不会改变ls本身。而只是更改类似于ls *中所示的扩展行为。
编辑:我的建议在下面的评论中。

很有趣,但你能展示一个例子命令吗? - felwithe
2
通过使用 shopt -s dotglob,你可以轻松地在想要打包的目录内执行 tar -cvpzf final.tar.gz * - Rod Elias
@felwithe 我没有展示一个例子,因为我决定当你使用 * 通配符进行打包时会发生非显而易见的行为。我也认为通过 shopt 更改默认行为是次优的。也就是说,避免非显而易见的和避免非默认的。如果可能的话,最好明确命名你想要打包的内容。 - H2ONaCl

8

您可以使用:

tar -cvpzf test.tgz * .??*

但是,这仅适用于名称>2的隐藏文件(以防止'.'和'..')


3
您可以使用以下命令压缩当前目录中的所有文件/文件夹(包括.hidden):
tar -zcvf compressed.tgz `ls -A -1`

最后一个参数是你想要压缩的文件夹。如果你传递ls -A -1,那么你传递的是当前目录下除了...以外的所有文件夹。 对于子目录来说,.hidden文件默认已经包含在压缩中。

如果目录中的文件名包含空格,则此命令无法正常工作。 - Florian Richard

2

Shell会展开通配符,因此tar甚至不会看到它们。如果您想这样做,必须明确添加它们(.*)。但是,最常见的方法是将单个目录打包,以便在解压缩时所有内容都放在同一个位置。


实际上,在 .* 上使用 tar 命令会将其打包到根目录(可能会很高),因此您可能不想这样做。 - H2ONaCl
更正:不是和根节点一样高。 - H2ONaCl
2
哦,没错。使用类似 .[a-zA-Z]* 这样的东西会更安全。但是,我总是更喜欢只打包一个目录(如果需要的话就是父目录)。 - Keith
这个注释讨论了tar和ls(list)命令,但在这种字体下很难看到。Shell可能负责扩展*通配符。然而,对于.通配符,tar和ls的行为不同,因此我不知道shell是否在点的情况下提供一致的行为。ls .忽略隐藏的内容(与tar不一致),ls -a .可以看到..(上面)目录,这也与tar将存档的内容不一致。tar只能使用.向下进行,除非您使用.*,我们已经讨论过了。 - H2ONaCl
点(.)在shell globbing中不是通配符,而是当前目录的名称。旧系统甚至有一个名为“.”的物理目录条目。因此,由于shell不会扩展它,它是一致的。 - Keith
然而,更令人困惑的是,如果你使用bash shell,你可以设置“ dotglob”选项(shopt -s dotglob)来禁用以点开头的名称的特殊处理。 - Keith

0
shopt -s dotglob

这将使得


7
欢迎来到StackOverflow!您是否忘记完成您的留言了? - Piotr Nowicki
Keith在他的评论中解释了这个答案。 - H2ONaCl

-2

这将打包所有隐藏的文件和目录

tar -cvzf hidden.tgz `ls -a | egrep [.][^.]+`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接