我还看到了与此错误相关的其他问题(例如提取 tar.gz 文件会返回“这看起来不像 tar 存档。”),但我不确定如何将它们应用到我的问题中:
一、下载文件:
$ wget --no-check-certificate https://wxpython.org/Phoenix/tools/doxygen-1.8.8-linux.bz2
--2017-04-06 15:06:11-- https://wxpython.org/Phoenix/tools/doxygen-1.8.8-linux.bz2
Resolving wxpython.org (wxpython.org)... 85.234.150.54
Connecting to wxpython.org (wxpython.org)|85.234.150.54|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3961996 (3.8M) [application/x-bzip2]
Saving to: ‘doxygen-1.8.8-linux.bz2’
100%[==============================================================================>] 3,961,996 734KB/s in 5.0s
2017-04-06 15:06:16 (778 KB/s) - ‘doxygen-1.8.8-linux.bz2’ saved [3961996/3961996]
然后,检查文件的文件类型:
$ file doxygen-1.8.8-linux.bz2
doxygen-1.8.8-linux.bz2: bzip2 compressed data, block size = 900k
嗯,这是“bzip2压缩数据”,我们来解压一下吧:
$ tar xjvf doxygen-1.8.8-linux.bz2
tar: This does not look like a tar archive
tar: Skipping to next header
tar: Archive contains ‘\351\357\377I\211\304H\211’ where numeric mode_t value expected
tar: Archive contains ‘A\270\001\0\0\0H\211ǹ\001’ where numeric time_t value expected
tar: Archive contains ‘\307\350\216v)\0I\307’ where numeric uid_t value expected
tar: Archive contains ‘\004$P\254|\0\2770’ where numeric gid_t value expected
@\2678\350\330\351\357\377\2778
tar: @\2678\350\330\351\357\377\2778: Unknown file type '', extracted as normal file
tar: @�8������8: implausibly old time stamp 1970-01-01 00:59:59
tar: Skipping to next header
tar: Exiting with failure status due to previous errors
我得到一个解压后的空文件:
$ ls -la @�8������8
-rwxrwxr-x 1 user user 0 Jan 1 1970 @?8??????8
奇怪的是,如果我使用file-roller
(档案管理器)并从 GUI 解压,我确实会得到一个解压的文件:
$ ls -la ~/Desktop/doxygen-1.8.8-linux
-rw-rw-r-- 1 user user 12283548 Apr 6 15:13 /home/user/Desktop/doxygen-1.8.8-linux
$ file ~/Desktop/doxygen-1.8.8-linux
/home/user/Desktop/doxygen-1.8.8-linux: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0eccee11d38322d5df3a1723651c2f18303e1188, not stripped
好的,那么这里发生了什么——为什么我不能从命令行解压它,以及如何使用命令行解压它?
编辑:实际上我可以用以下方法解压它:
$ bzip2 -d doxygen-1.8.8-linux.bz2
$ file doxygen-1.8.8-linux
doxygen-1.8.8-linux: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0eccee11d38322d5df3a1723651c2f18303e1188, not stripped
...所以唯一剩下的问题是——为什么我不能tar
像往常一样使用它?
答案1
tar
只是将多个文件复制到一个大.tar
文件中,而不进行压缩。bzip2
、gzip
、xz
是针对单个文件(即 )的文件压缩器tar
。扩展名为.tar.gz
、.tar.xz
、.tar.bz2
或.tbz
( 2
)、.txz
、.tgz
等。
tar
只能处理.tar
使用 bzip2、xz、gzip 压缩或未压缩的文件。但是不是非 tar'ed .bz2
,.xz
档案。
非 tar 格式的 bzip 文件可以用 来提取bzip2 -d file.bz2
。
答案2
您的文件“看起来不像 tar 存档”的原因是不是tar 存档,但只是一个 bzip2 压缩的可执行文件。您可以从file
命令输出中看出这一点,也可以从文件没有.tar.bz2
文件扩展名这一事实中看出这一点.bz2
(当然,从技术上讲,可以将任何文件重命名为具有任何扩展名)。
考虑到柏油和bzip2作为具有不同目的的单独层:tar 将一堆不同的文件组合成一个大文件,而 bzip2 通过以更紧凑的方式对重复部分进行编码来压缩包含重复数据的文件(通常是 tar 的输出)。
Tar 通常与 bzip2 一起使用(或压缩或其他类似的文件压缩程序)有两个主要原因:
Tar 档案是 bzip2 压缩的绝佳候选对象,因为它们通常包含大量重复数据,并且通常希望将它们压缩得尽可能小以节省空间。
此外,顾名思义,tar 档案通常用于归档数据不会被频繁访问或修改。因此,bzip2 压缩和解压缩导致访问和修改内容变慢这一事实并不是一个特别大的问题。
根据设计,bzip2(以及 gzip 等)无法一次压缩多个文件。如果您想要制作一个包含多个文件的 bzip2 压缩档案,则需要首先将文件打包到一起。
这种设计是 Unix 哲学的一部分,即让每个工具只做一件事,并把它做好。Tar 将文件连接在一起。Bzip2 压缩文件。与其他流行的压缩工具相比,这种模块化设计的一个优点是压缩两者的设计都兼具两者的优点,即每个部分都可以轻松替换而不会影响其他部分。例如,bzip2 是(在某些方面)改进的 gzip 的替代品,而 gzip 又是旧版 gzip 的替代品压缩程序。所有这些程序,以及任何其他更好的文件压缩程序(例如西泽) 现在或将来存在,都可以用来压缩相同的 tar 档案。
由于 tar 和 xz / bzip2 / gzip / compress 经常一起使用,因此许多常见的 tar 实现(包括 Linux 上通常使用的 GNU tar)提供了一些额外的便利功能来处理压缩档案。特别是,它们可以通过命令行开关被告知使用这些压缩程序之一自动压缩其打包输出,并且它们可能能够检测到已压缩的档案并在解压之前自动解压缩它们。但是,这些功能只是为了方便用户:只需通过 bzip2 或其他文件压缩器管道传输 tar 的输入/输出即可获得完全相同的结果。
然而,有时你做想要单独使用 tar 或 bzip2 而不使用另一个。值得注意的是,如果您只有一个要压缩的大文件,那么您真的不需要先对其进行 tar 处理,而直接将 bzip2 应用于原始文件会更有效。您似乎拥有的就是这样:一个大型的 bzip2 压缩文件。
如果您尝试将此文件提供给 tar,它将首先正确检测到它是 bzip2 压缩的,并尝试在进一步处理之前对其进行解压缩。但由于您明确调用了 tar,它预计实际上会收到一个(可能是压缩的)tar 存档,并且当它在解压缩输入后找不到它期望的内容时,它会给出您看到的错误消息。
相反,正如迈克尔·D.已经注意到在评论中,您可以直接使用 bzip2 解压缩此文件,方法是:
bzip2 -d doxygen-1.8.8-linux.bz2
或(等效地):
bunzip2 doxygen-1.8.8-linux.bz2
默认情况下,当像这样调用 b(un)zip2 时,解压后的文件将具有与原始文件相同的名称,只是没有扩展名.bz2
。成功解压后,原始压缩文件将被自动删除。(如果您不希望这样,请将-k
或--keep
选项传递给 b(un)zip2。)当然,您也可以使用以下命令重新压缩未压缩的文件:
bzip2 doxygen-1.8.8-linux
或者,您可以简单地通过 stdin 将数据传递到 b(un)zip2,并通过 stdout 接收相应的(未)压缩数据,如下所示:
bunzip2 < doxygen-1.8.8-linux.bz2 > doxygen-1.8.8-linux-or-whatever
它的作用与上面的 bunzip2 命令相同,不同之处在于它不会(也不能)自动删除输入文件,并且您可以为输出文件指定任何您想要的名称。
更有用的是,您还可以将 b(un)zip2 的输入和/或输出通过管道传输到另一个程序。例如,您无需先使用以下命令将压缩文件下载到磁盘:获得然后解压缩它,你可以将 wget 的输出直接导入到 bunzip2 中:
wget --output-document=- \
https://wxpython.org/Phoenix/tools/doxygen-1.8.8-linux.bz2 \
| bunzip2 > doxygen-1.8.8-linux
开关--output-document=-
(可以缩写为-O -
)告诉 wget 将下载的数据写入 stdout 而不是保存到磁盘。最后一行将 wget 的输出通过管道传输到 bunzip2,并将 bunzip2 的输出定向到文件doxygen-1.8.8-linux
。反斜杠只是标记我为了便于阅读而将命令拆分为多行的位置;shell 将忽略它们以及它们后面的换行符。