Python zipfile从二进制文件中删除执行权限

前端之家收集整理的这篇文章主要介绍了Python zipfile从二进制文件中删除执行权限前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
不确定为什么会发生这种情况,但是当我在命令行中运行解压缩文件(例如apache-groovy-binary-2.4.7.zip)时……

>目录是rwx-r-xr-x
>文件是rwxr-xr-x或rw-r – r–

但是当我从同一文件上的Python 2.7脚本运行zipfile.extractall()时……

>目录是rwx-r-x —
>文件都是rw-r —- – 甚至是那些应该是可执行文件文件.

我的umask设置是0027-这部分解释了发生了什么,但为什么可执行位从所有文件删除

让Python在命令行版本中采用类似行为的最简单的解决方法是什么(当然,除了炮轰外!)?

解决方法

原因可以在zipfile.py中的_extract_member()方法中找到,它只调用shutil.copyfileobj(),它将在没有任何执行位的情况下写入输出文件.

解决这个问题的最简单方法是通过继承ZipFile并更改extract()(或在扩展版本中修补.默认情况下它是:

def extract(self,member,path=None,pwd=None):
    """Extract a member from the archive to the current working directory,using its full name. Its file information is extracted as accurately
       as possible. `member' may be a filename or a ZipInfo object. You can
       specify a different directory using `path'.
    """
    if not isinstance(member,ZipInfo):
        member = self.getinfo(member)

    if path is None:
        path = os.getcwd()

    return self._extract_member(member,path,pwd)

应该更改最后一行以实际根据原始属性设置模式.你可以这样做:

import os
from zipfile import ZipFile,ZipInfo

class MyZipFile(ZipFile):

    def extract(self,pwd=None):
        if not isinstance(member,ZipInfo):
            member = self.getinfo(member)

        if path is None:
            path = os.getcwd()

        ret_val = self._extract_member(member,pwd)
        attr = member.external_attr >> 16
        os.chmod(ret_val,attr)
        return ret_val


with MyZipFile('test.zip') as zfp:
    zfp.extractall()

(以上是基于Python 3.5并假设zipfile名为test.zip)

猜你在找的Python相关文章