Desde un script de Python 3, estoy comprimiendo una carpeta.

El comando que normalmente usaría en Terminal, y funciona , es

zip -P P4ssw0rd somefolder.zip somefolder/*

(-P lo uso para el cifrado de contraseña, y el /* al final porque quiero comprimir el contenido de la carpeta, si no lo incluyo el archivo solo contiene una carpeta vacía)

Esto crea con éxito un somefolder.zip con el contenido correcto protegido por contraseña.

Cuando estoy ejecutando este comando desde mi script, estoy usando

subprocess.call(['zip', '-P', 'P4ssw0rd', 'somefolder.zip', 'somefolder/*'])

Esto me da un error zip (el mismo tipo que obtendría si escribiera el comando directamente en la Terminal, pero si escribí mal el nombre de la carpeta, por ejemplo zip -P P4ssw0rd somefolder.zip someOtherfolder/*)

La advertencia dice:

advertencia zip: nombre no coincidente: alguna carpeta / *

Según tengo entendido, de alguna manera interpreta el / y el * como parte del nombre de la carpeta, y no como si tratara de navegar dentro de la carpeta ...

¿Alguna idea?


Para hacer las cosas más confusas:

Si el somefolder.zip ya existe, entonces

subprocess.call(['zip', '-P', 'P4ssw0rd', 'somefolder.zip', 'somefolder/*'])

Se ejecutará Dice que está actualizando el contenido de la carpeta, pero realmente nada cambia por lo que puedo decir del archivo en sí. Sin embargo, si cambio el 'somefolder/*' a algo más como 'someOtherfolder/*', nuevamente arroja un error de nombre no coincidente.

0
small_cat_destroyer 2 oct. 2019 a las 17:26

4 respuestas

La mejor respuesta

Tras una inspección adicional, descubrí que os.system() propuesto por @ImranD, aunque funciona, se recomienda reemplazarlo por el nuevo módulo supbrocess. Entonces, de hecho, la forma más correcta sería utilizar subprocess.call(), sin embargo, los argumentos deben proporcionarse de manera diferente.

Por ejemplo, en mi pregunta original, la forma correcta (y funcional) de usar subprocess.call() sería la siguiente:

subprocess.call('zip -P P4ssw0rd somefolder.zip somefolder/*', shell=True)

En realidad, mi línea se parece más a:

subprocess.call('zip -P P4ssw0rd ' + archiveName + ' ' + folderToArchive, shell=True)

Donde archiveName y folderToArchive son cadenas (creo que se explican por sí mismas) que he modificado anteriormente.

Documentación:

https://docs.python.org/3.7/library/subprocess.html#replacing-older-functions-with-the-subprocess-module

O más específicamente:

https://docs.python.org/3.7/library/subprocess.html#replacing-os-system

0
small_cat_destroyer 3 oct. 2019 a las 10:24

Probablemente sea porque su script se está ejecutando desde una ubicación diferente. intente pasar la ruta absoluta en lugar de la ruta relativa. p.ej.

subprocess.call(['zip', '-P', 'P4ssw0rd', '-j', 'somefolder.zip', '/full/path/to/somefolder/*'])
0
m0etaz 2 oct. 2019 a las 14:47

Probablemente debería convertir manualmente glob * a la lista de archivos

dir = 'somefolder'
files = [ dir + f for f in listdir(dir) ]
cmd = ['zip', '-P', 'P4ssw0rd', 'somefolder.zip' ] + files
subprocess.call(cmd)
0
P. Dmitry 2 oct. 2019 a las 15:40

Si no le importa usar algo más que el módulo de subproceso, esto funciona:

os.popen("zip -P P4ssw0rd somefolder.zip somefolder/*")

Por supuesto, no olvides import os de antemano.

1
ImranD 2 oct. 2019 a las 15:01
58203581