Установить права на сжатый файл в Python
У меня есть файл test.txt
то есть внутри почтового архива test.zip
, Разрешения на test.txt
находятся вне моего контроля, когда они сжаты, но теперь я хочу, чтобы они были доступны для записи в группе. Я извлекаю файл с помощью Python и не хочу выходить в оболочку.
РЕДАКТИРОВАТЬ: Вот что у меня так далеко:
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
,
4 ответа
У меня была похожая проблема с вами, так что здесь приведен фрагмент кода из моего материала, который, я считаю, должен помочь здесь.
# 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.
Согласно документации, unzip устанавливает права доступа для тех, кто хранится в Unix. Также оболочка umask не используется. Лучше всего перед тем, как архивировать файл, убедитесь, что он настроен.
Поскольку вы не можете этого сделать, вам придется попытаться сделать то, что вы пытались сделать (и заставить его работать в Debian.)
С библиотекой zipfile в Pythons возникло несколько проблем, в том числе установил режим writestr для режима записи файла в некоторых системах или установил zip-систему для windows вместо unix. Таким образом, ваши противоречивые результаты могут означать, что ничего не изменилось.
Так что вам может быть совершенно не повезло.
Ответ @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)
Извлечь в стандартный вывод (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
(да, я знаю, что вы пометили этот "питон":-))