Linux 为什么解压会提取最后一个连接的ZIP?
我发现以下行为出乎意料:Linux 为什么解压会提取最后一个连接的ZIP?,linux,unix,unzip,Linux,Unix,Unzip,我发现以下行为出乎意料: $ mkdir tmp && cd tmp/ $ for example in a b c ; do echo $example > $example.txt ; done $ for file in `ls *` ; do zip $file.zip $file ; done $ cat a.txt.zip b.txt.zip c.txt.zip > concatenated.zip $ unzip concatenated.zip -d
$ mkdir tmp && cd tmp/
$ for example in a b c ; do echo $example > $example.txt ; done
$ for file in `ls *` ; do zip $file.zip $file ; done
$ cat a.txt.zip b.txt.zip c.txt.zip > concatenated.zip
$ unzip concatenated.zip -d output
$ ls output/
c.txt # unexpected
另一方面,p7zip实现了以下功能:
$ rm -r output/
$ 7z x concatenated.zip -ooutput/
$ ls output/
a.txt
为什么解压会提取最后一个连接的ZIP?它是否从EOF向后遍历,直到找到PK文件签名
它是否从EOF向后遍历,直到找到PK文件签名
对。以下是解压
将要做的事情:
- 在zip文件的末尾查找“中心目录记录的结尾”(EOCD)
- 读取记录并遵循“中心目录起始偏移量”
- 读取中心目录(它包含存档中每个条目的列表)
- 阅读每个条目并遵循“本地标题的相对偏移量”
- 读取带有数据的本地头并将其提取
unzip
告诉您:
warning [concatenated.zip]: 324 extra bytes at beginning or within zipfile
(attempting to process anyway)
它查找c.txt.zip
的中心目录,只看到一个条目(c.txt
),只提取一个文件
考虑到zip文件的结构,我认为这是合乎逻辑的。自解压zip文件使用这种方式:文件以二进制文件开始解压,以实际的zip内容结束(请参见unzipsfx
和zip-a
)
如果文件不像zip文件那样开始,7z将从末尾开始尝试:
# not a.txt.zip, but a.txt
$ cat a.txt b.txt.zip c.txt.zip > prepended.zip
# fix offset
$ zip -A prepended.zip
$ unzip -l prepended.zip
Archive: prepended.zip
Length Date Time Name
--------- ---------- ----- ----
2 2016-11-22 20:29 c.txt
--------- -------
2 1 file
$ 7z l prepended.zip
[...]
Path = prepended.zip
Warning: The archive is open with offset
Type = zip
Physical Size = 326
Embedded Stub Size = 164
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2016-11-22 20:29:05 ..... 2 2 c.txt
------------------- ----- ------------ ------------ ------------------------
2016-11-22 20:29:05 2 2 1 files
注意zip-A
要修复偏移:
-A选项告诉zip调整存储在归档中的条目偏移量,以考虑这个“前导”数据
我不知道您想要实现什么,但是连接zip文件可能不是最简单的方法(将它们提取回来并不容易)