相关的Python问题提供了对问题首先存在的原因的见解。 https://bugs.python.org/issue 18262和{a2}
重要的部分是4.4.2版本号by (2字节)
4.4.2.1 theupperbyteindicatesthecompatibilityofthefile
attribute information.iftheexternalfileattributes
arecompatiblewithms-dosandcanbereadbypkzipfor
dos 2.04版gthenthisvaluewillbezero.if these
attributes are not compatible,then this value will
identifythehostsystemonwhichtheattributesare
compatible.softwarecanusethisinformationtodetermine
thelinerecordformatfortextfilesetc。
4.4.2.2 thecurrentmappingsare :
0-ms-dosandos/2 (fat/vfat/fat 32文件系统) )。
1 - Amiga 2 - OpenVMS
3 - UNIX 4 - VM/CMS
5 - Atari ST 6 - OS/2 H.P.F.S。
7-MAC OS h8-z-system
9 - CP/M 10 - Windows NTFS
11-MVS(OS/390-z/OS ) 12 - VSE
13 - Acorn Risc 14 - VFAT
15 -备用MVS 16-beos
17 - Tandem 18 - OS/400
19-OSx(Darwin ) 20 thru 255 - unused
.
4.4.15外部文件属性: (4字节)。
themappingoftheexternalattributesis
主机系统从属(see ' version made by ' ).For
MS-DOS,theloworderbyteisthems-dos目录
attribute byte.ifinputcamefromstandardinput,this
field is set to zero。
也就是说,外部文件属性是系统特定的。 如果解释不同系统的外部文件属性,情况可能会恶化。 如果只关心UNIX,可以选中ZipInfo.created_system并将其与3 (对于UNIX )进行比较。 不幸的是,规范无助于进一步说明外部属性。 在
这是一个相当观察的问题,但这似乎是共识。 在
将它们放在一起:来自zipfile导入zipfile
ZIP_UNIX_SYSTEM=3
ef extract _ all _ with _ permission (ZF,target_dir ) :
for info in zf.infolist () :
extracted_path=ZF.extract(info,target_dir )。
if info.create _ system==zip _ UNIX _ system 3360
UNIX _ attributes=info.external _ attr 16
if unix_attributes:
操作系统. chmod (扩展路径,unix_attributes ) ) ) ) ) ) ) ) )。
withzipfile(sample.zip ),(r ) ) as zf:
extract_all_with_permission(ZF,'/tmp ' ) )
为什么我们必须首先保留权限,可能会出现问题。 有些人可能会说我们只想留下可行标记。 在这种情况下,一个稍微安全的选择是只恢复可执行标志并只用于文件。 在from zipfile导入zipfile中
from stat import S_IXUSR
ZIP_UNIX_SYSTEM=3
ef extract _ all _ with _ executable _ permission (ZF,target_dir ) :
for info in zf.infolist () :
extracted_path=ZF.extract(info,target_dir )。
if info.create _ system==zip _ UNIX _ syste mandos.path.isfile (extracted _ path ) :
UNIX _ attributes=info.external _ attr 16
if unix_attributes S_IXUSR:
OS.chmod(extracted_path,OS.stat ) extracted _ path (.ST _ mode|s _ ixusr ) )。
withzipfile(sample.zip ),(r ) ) as zf:
extract _ all _ with _ executable _ permission (ZF,'/tmp ' )