2010-05-17 9 views
32

¿Cuál es la "forma de python" para establecer de forma recursiva el propietario y el grupo en los archivos de un directorio? Podría pasarle un comando 'chown -R' a Shell, pero siento que me falta algo obvio.¿Cuál es la forma de Python para establecer permisos de archivos recursivamente?

estoy curioseaba con esto:


import os 
path = "/tmp/foo" 
for root, dirs, files in os.walk(path): 
    for momo in dirs: 
    os.chown(momo, 502, 20) 

Esto parece funcionar para establecer el directorio, pero falla cuando se aplica a los archivos. Sospecho que los archivos no obtienen la ruta completa, por lo que chown falla, ya que no puede encontrar los archivos. El error es:

'OSError: [Errno 2] No existe el fichero o directorio: 'foo.html'

Lo estoy pasando por alto aquí?

Respuesta

35

El dirs y files listas son siempre relativos a root - es decir, que son los basename() de los archivos/carpetas, es decir, no tienen un / en ellos (o \ en windows). Que necesita para unirse a los dirs/archivos a root para obtener toda su trayectoria si desea que su código funcione a niveles infinitos de recursividad:

import os 
path = "/tmp/foo" 
for root, dirs, files in os.walk(path): 
    for momo in dirs: 
    os.chown(os.path.join(root, momo), 502, 20) 
    for momo in files: 
    os.chown(os.path.join(root, momo), 502, 20) 

Estoy sorprendido el módulo shutil no tiene una función para este .

+0

Esto tiene un error que acabo de ver en el código de producción de mi compañero de trabajo :-) No se está recogiendo el directorio de nivel superior especificado. Sugerí una edición con una corrección, con suerte se aprueba. –

+0

Así que mi edición fue rechazada - buena idea para cualquiera que use esto y encuentre el error donde '/ tmp/foo' NO tiene sus permisos modificados. Buen trabajo moderando SO pythonians –

+0

@AvindraGoolcharan buena captura - ¡con suerte eso era lo que tenías en mente! –

4

tratar os.path.join(root,momo) que le dará ruta completa

1

No se olvide el bucle for f in files, tampoco. Del mismo modo, recuerda os.path.join(root, f) para obtener la ruta completa.

5
import os 
path = "/tmp/foo" 
for root, dirs, files in os.walk(path): 
    for momo in dirs: 
    os.chown(momo, 502, 20) 
    for file in files: 
    fname = os.path.join(root, file) 
    os.chown(fname, aaa, bb) 

sustituto aaa y bb como desee

+0

Como en el comentario aceptado, '/ tmp/foo' NO tendrá el propietario configurado correctamente. Ver mis comentarios arriba. –

2

Aquí hay una función que escribí que usa glob para enumerar recursivamente archivos y cambiar sus permisos.

import os 
import glob 
def recursive_file_permissions(path,mode,uid=-1,gid=-1): 
     ''' 
     Recursively updates file permissions on a given path. 
     UID and GID default to -1, and mode is required 
     ''' 
    for item in glob.glob(path+'/*'): 
     if os.path.isdir(item): 
      recursive_file_permissions(os.path.join(path,item),mode,uid,gid) 
     else: 
      try: 
       os.chown(os.path.join(path,item),uid,gid) 
       os.chmod(os.path.join(path,item),mode) 
      except: 
       print('File permissions on {0} not updated due to error.'.format(os.path.join(path,item))) 

que no es perfecto, pero me llevó a donde tenía que estar

-2

uso os.lchown en lugar de os.chown para cambiar vincularse y archivos juntos.

Cuestiones relacionadas