descomprimir - ¿Cómo configuro los permisos(atributos) en un archivo en un archivo ZIP usando el módulo zipfile de Python?
descomprimir rar python (5)
Cuando lo haces así, ¿funciona bien?
zf = zipfile.ZipFile("something.zip")
for name in zf.namelist():
f = open(name, ''wb'')
f.write(self.read(name))
f.close()
Si no es así, te sugiero que os.chmod
un os.chmod
en el ciclo for con 0777 permisos como este:
zf = zipfile.ZipFile("something.zip")
for name in zf.namelist():
f = open(name, ''wb'')
f.write(self.read(name))
f.close()
os.chmod(name, 0777)
Cuando zipfile
archivos de un archivo ZIP creado con el módulo de archivo zipfile
Python, todos los archivos no se pueden escribir, leer solo, etc.
El archivo se está creando y extrayendo bajo Linux y Python 2.5.2.
Lo mejor que puedo decir es que necesito establecer la propiedad ZipInfo.external_attr
para cada archivo, pero esto no parece estar documentado en ningún lugar que pueda encontrar, ¿alguien puede aclararme?
Esto parece funcionar (gracias Evan, poniéndolo aquí para que la línea esté en contexto):
buffer = "path/filename.zip" # zip filename to write (or file-like object)
name = "folder/data.txt" # name of file inside zip
bytes = "blah blah blah" # contents of file inside zip
zip = zipfile.ZipFile(buffer, "w", zipfile.ZIP_DEFLATED)
info = zipfile.ZipInfo(name)
info.external_attr = 0777 << 16L # give full access to included file
zip.writestr(info, bytes)
zip.close()
Todavía me gustaría ver algo que documente esto ... Un recurso adicional que encontré fue una nota en formato de archivo Zip: http://www.pkware.com/documents/casestudies/APPNOTE.TXT
Este enlace tiene más información que cualquier otra cosa que he podido encontrar en la red. Incluso la fuente zip no tiene nada. Copiando la sección relevante para la posteridad. Este parche no se trata realmente de documentar este formato, lo que demuestra cuán patética (es decir, inexistente) es la documentación actual.
# external_attr is 4 bytes in size. The high order two
# bytes represent UNIX permission and file type bits,
# while the low order two contain MS-DOS FAT file
# attributes, most notably bit 4 marking directories.
if node.isfile:
zipinfo.compress_type = ZIP_DEFLATED
zipinfo.external_attr = 0644 << 16L # permissions -r-wr--r--
data = node.get_content().read()
properties = node.get_properties()
if ''svn:special'' in properties and /
data.startswith(''link ''):
data = data[5:]
zipinfo.external_attr |= 0120000 << 16L # symlink file type
zipinfo.compress_type = ZIP_STORED
if ''svn:executable'' in properties:
zipinfo.external_attr |= 0755 << 16L # -rwxr-xr-x
zipfile.writestr(zipinfo, data)
elif node.isdir and path:
if not zipinfo.filename.endswith(''/''):
zipinfo.filename += ''/''
zipinfo.compress_type = ZIP_STORED
zipinfo.external_attr = 040755 << 16L # permissions drwxr-xr-x
zipinfo.external_attr |= 0x10 # MS-DOS directory flag
zipfile.writestr(zipinfo, '''')
Además, este enlace tiene lo siguiente. Aquí el byte de orden bajo presumiblemente significa el byte más a la derecha (el más bajo) de los cuatro bytes. Así que este es para MS-DOS y, presumiblemente, se puede dejar como cero.
atributos de archivos externos: (4 bytes)
The mapping of the external attributes is host-system dependent (see ''version made by''). For MS-DOS, the low order byte is the MS-DOS directory attribute byte. If input came from standard input, this field is set to zero.
Además, el archivo fuente unix / unix.c en las fuentes del programa zip de InfoZIP, descargado de los archivos de Debian, tiene lo siguiente en los comentarios.
/* lower-middle external-attribute byte (unused until now):
* high bit => (have GMT mod/acc times) >>> NO LONGER USED! <<<
* second-high bit => have Unix UID/GID info
* NOTE: The high bit was NEVER used in any official Info-ZIP release,
* but its future use should be avoided (if possible), since it
* was used as "GMT mod/acc times local extra field" flags in Zip beta
* versions 2.0j up to 2.0v, for about 1.5 years.
*/
Así que tomando todo esto en conjunto, parece que solo se usa realmente el segundo byte más alto, al menos para Unix.
EDIT: pregunté sobre el aspecto de Unix de esto en Unix.SX, en la pregunta " El atributo de archivo externo del formato zip ". Parece que tengo un par de cosas mal. Específicamente, los dos bytes superiores se usan para Unix.
Mira esto: establece permisos en un archivo comprimido en python
No estoy del todo seguro de si eso es lo que quieres, pero parece ser.
La línea clave parece ser:
zi.external_attr = 0777 << 16L
Parece que establece los permisos a 0777
allí.
Las respuestas anteriores no me funcionaron (en OS X 10.12). Descubrí que, además de los indicadores ejecutables (octal 755), también necesito establecer el indicador de "archivo normal" (octal 100000). Encontré esto mencionado aquí: https://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute
Un ejemplo completo:
zipname = "test.zip"
filename = "test-executable"
zip = zipfile.ZipFile(zipname, ''w'', zipfile.ZIP_DEFLATED)
f = open(filename, ''r'')
bytes = f.read()
f.close()
info = zipfile.ZipInfo(filename)
info.date_time = time.localtime()
info.external_attr = 0100755 << 16L
zip.writestr(info, bytes, zipfile.ZIP_DEFLATED)
zip.close()
Un ejemplo completo de mi caso de uso específico, crear un archivo comprimido de un .app para que todo en la carpeta Contents/MacOS/
sea ejecutable: https://gist.github.com/Draknek/3ce889860cea4f59838386a79cc11a85