Установить права на сжатый файл в Python - PullRequest
7 голосов
/ 11 ноября 2008

У меня есть файл test.txt, который находится внутри zip-архива test.zip. Разрешения на test.txt вне моего контроля, когда они сжаты, но теперь я хочу, чтобы они были доступны для записи в группе. Я извлекаю файл с помощью Python и не хочу выходить в оболочку.

EDIT: Вот что у меня так далеко:

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()

Это прекрасно работает на OS X, использующей 2.5.1, но не работает на моем домашнем компьютере (Debian, Python 2.4 и 2.5) или на RHEL 5 с Python 2.4. На любом, кроме 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.

Ответы [ 3 ]

4 голосов
/ 27 февраля 2009

У меня была похожая проблема с вами, так что вот код спина из моих вещей, это, я считаю, должно помочь здесь.

# 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 здесь, я знаю о некоторых несовместимостях с некоторыми версиями поддержки zipfile в Python.

1 голос
/ 11 ноября 2008

Согласно документации, unzip устанавливает права доступа для тех, кто хранится в Unix. Также оболочка umask не используется. Лучше всего перед тем, как архивировать файл, убедитесь, что он настроен.

Поскольку вы не можете этого сделать, вам придется попытаться сделать то, что вы пытались сделать (и заставить его работать в Debian.)

Был ряд проблем с библиотекой zipfile Pythons, включая установку режима writestr для режима записи файла в некоторых системах или установку zip-системы в windows вместо unix. Таким образом, ваши противоречивые результаты могут означать, что ничего не изменилось.

Так что вам может не повезти.

0 голосов
/ 11 ноября 2008

Извлечь в стандартный вывод (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

(да, я знаю, что вы пометили этот 'питон' :-))

...