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

标签 python python-2.7

不确定为什么会这样,但是当我在命令行运行解压缩文件(例如 apache-groovy-binary-2.4.7.zip)时...

  • 目录是 rwx-r-xr-x
  • 文件是 rwxr-xr-xrw-r--r--

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

  • 目录是 rwx-r-x---
  • 文件都是 rw-r----- - 即使是按照上面的规定应该是可执行文件。

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

让 Python 采用与命令行版本相似的行为的最简单修复方法是什么(当然,除了 shelling out!)?

最佳答案

原因可以在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
import sys
from zipfile import ZipFile, ZipInfo

class MyZipFile(ZipFile):

    if sys.version_info < (3, 6):

        def extract(self, member, path=None, pwd=None):
            if not isinstance(member, ZipInfo):
                member = self.getinfo(member)
            if path is None:
                path = os.getcwd()
            ret_val = self._extract_member(member, path, pwd)
            attr = member.external_attr >> 16
            os.chmod(ret_val, attr)
            return ret_val

    else:

        def _extract_member(member, ZipInfo):
            if not isinstance(member, ZipInfo):
                member = self.getinfo(member)
            path = super(ZipFile, self)._extract_member(member, targetpath, pwd)

            if member.external_attr >  0xffff:
                 os.chmod(path, member.external_attr >> 16)
            return path


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

(以上基于 Python 3.5 并假设压缩文件名为 test.zip)

关于Python zipfile 从二进制文件中删除执行权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39296101/

相关文章:

python - 试图找到图像中黑色像素的百分比(Python 2)

python - 如何使用没有类的 BeautifulSoup 提取值

python-2.7 - 从 Python 2 更改为 Python 3 后,PyCharm 中缺少调试链接

python - 如何从 Tensorflow 中的张量中获取特定行?

python - scipy.integrate.quad() 不使用 lambda

python - 如何将 Pandas DataFrame 的每一列与其他列相乘?

python - datetime.combine() 和 pytz.localize() 之间的区别

python - 如何在OpenCV Python中将滤镜应用于网络摄像头

python - 打印功能打印最近耗时的东西

python - 如何对 python 版本开关进行单元测试