8

我有一个test.txt位于 zip 存档中的文件test.zip。压缩后的权限test.txt不在我的控制范围内,但现在我希望它们是组可写的。我正在使用 Python 提取文件,并且不想逃到 shell 中。

编辑: 这是我到目前为止所得到的:

import zipfile

z = zipfile.ZipFile('test.zip', 'w')
zi = zipfile.ZipInfo('test.txt')
zi.external_attr = 0777 << 16L
z.writestr(zi, 'FOO')
z.close()

z = zipfile.ZipFile('test.zip', 'r')
for name in z.namelist():
    newFile = open(name, "wb")
    newFile.write(z.read(name))

    newFile.close()
z.close()

这在使用 2.5.1 的 OS X 上完美运行,但不适用于我的 home box(Debian、Python 2.4 和 2.5)或使用 Python 2.4 的 RHEL 5。除了 OS X 之外,它不会出错,但也不会更改权限。任何想法为什么?另外,如何writestr()工作?我知道我在这里使用不正确。

有没有办法做到这一点os.chmod(提取文件的用户在提取文件后没有使用权限os.chmod)?我对 zip 文件具有完全写入权限。

更多信息:

> ls -l test.zip
-rwxrwxrwx 1 myuser mygroup 2008-11-11 13:24 test.zip
> unzip test.zip
Archive:  test.zip
  inflating: test.txt 
> ls -l test.txt
-rw-r--r-- 1 myuser mygroup 2008-11-11 13:34 test.txt

提取的用户不是myuser,而是在mygroup

4

4 回答 4

6

我遇到了类似的问题,所以这是我的东西中的代码spinet,我相信这在这里应该有所帮助。

# extract all of the zip
for file in zf.filelist:
    name = file.filename
    perm = ((file.external_attr >> 16L) & 0777)
    if name.endswith('/'):
        outfile = os.path.join(dir, name)
        os.mkdir(outfile, perm)
    else:
        outfile = os.path.join(dir, name)
        fh = os.open(outfile, os.O_CREAT | os.O_WRONLY , perm)
        os.write(fh, zf.read(name))
        os.close(fh)
    print "Extracting: " + outfile

您可能会做类似的事情,但插入您自己的逻辑来计算您的烫发值。我应该注意,我在这里使用的是 Python 2.5,我知道与 Python 的 zipfile 支持的某些版本存在一些不兼容性。

于 2009-02-27T20:12:53.857 回答
1

根据文档, unzip 将权限设置为在 unix 下存储的权限。此外,不使用外壳 umask。最好的办法是确保在压缩文件之前设置 perms。

既然你不能这样做,你将不得不尝试做你想做的事情(并让它在 Debian 下工作。)

Python 的 zipfile 库存在许多问题,包括将 writestr 的模式设置为某些系统上正在写入的文件的模式,或者将 zip 系统设置为 windows 而不是 unix。所以你不一致的结果可能意味着什么都没有改变。

所以你可能完全不走运。

于 2008-11-11T04:10:07.080 回答
1

@Petriborg 的答案仍然是相关的,但要使用 Python 3,这里有一个包含必要修复的版本:

import os
import zipfile

zip_file = "/path/to/archive.zip"
out_dir = "/path/to/output"

os.makedirs(out_dir, exist_ok=True)

with zipfile.ZipFile(zip_file, "r") as zf:
    for file in zf.filelist:
        name = file.filename
        perm = ((file.external_attr >> 16) & 0o777)
        print("Extracting: " + name)
        if name.endswith("/"):
            os.mkdir(os.path.join(out_dir, name), perm)
        else:
            outfile = os.path.join(out_dir, name)
            fh = os.open(outfile, os.O_CREAT | os.O_WRONLY, perm)
            os.write(fh, zf.read(name))
            os.close(fh)
于 2021-03-31T01:44:25.800 回答
0

提取到标准输出(unzip -p)并重定向到文件?如果 zip 中有多个文件,您可以列出 zip 内容,然后一次提取一个。

for n in `unzip -l test.zip | awk 'NR > 3 && NF == 4 { print $4 }'`; do unzip -p test.zip $n > $n; done

(是的,我知道你标记了这个'python' :-))

于 2008-11-11T04:16:56.257 回答