Python Shutil.copy falla en sistemas de archivos FAT (Ubuntu)
Pregunta
Problema:El uso deshutil.copy() para copiar un archivo a un sistema de archivos montado en FAT16 en Linux falla (Python 2.7.x).La falla es un error interno de Shutil y en realidad falla en Shutil.chmod, que parece ejecutar Shutil.copy.
Shell chmod también falla, ya que FAT no admite permisos.
Preguntas:¿Hay alguna manera clara de evitar esto?Sé que tengo varias opciones, por ejemplo:
- Usar copyfile: no es ideal ya que requiere una ruta completa, no solo el directorio de destino, pero es factible
- Ejecute shell cp para copiar archivos
- Escriba su propia función de copia que no intente cambiar los modos de archivo
¿Hay alguna forma de solucionar esto en Python O en las opciones de montaje FAT?Ahora monto el sistema de archivos dentro de mi programa ejecutando mount -t vfat -o umask=000 /dev/loop0 /mnt/foo
Detectar la excepción no ayuda, ya que la excepción ocurre dentro de Shutil.copy y Shutil.copy() parece eliminar el archivo de destino cuando detecta IOException de Shutil.chmod(), antes de pasar IOException a la función de llamada.
¿Alguna idea o debería elegir una entre 1 y 3?
Hannu
Solución
bueno, engaño en este caso.
Si sé que el objetivo es un sistema de archivos donde falla chmod
, simplemente eliminé el método chmod
en el paquete del sistema operativo usando del os.chmod
, y esto permite que la copia tenga éxito.
>>> import os
>>> print hasattr(os, 'chmod')
True
>>> foo = os.chmod
>>> del os.chmod
>>> print hasattr(os, 'chmod')
False
Esto ahora le permite realizar la copia sin fallar en el Chmod.Luego volvemos a habilitarlo asignando el atributo hacia atrás.
>>> setattr(os, 'chmod', foo)
>>> print hasattr(os, 'chmod')
True
Otros consejos
Usar shutil.copyfile
, no requiere ruta completa.
Eliminando os.chmod
globalmente es no una buena idea.
$ mkdir folder
$ touch folder/a
$ python2.7 -c 'import shutil; shutil.copyfile("folder/a","folder/b")'
$ ls -rthla folder/
total 0
drwxr-xr-x+ Apr 17 12:49 ../
-rw-r--r-- Apr 17 12:49 a
-rw-r--r-- Apr 17 12:50 b
drwxr-xr-x+ Apr 17 12:50 ./
Como puede ver en el código fuente de Python de Shutil (/usr/lib/python2.7/shutil.py
), no hay consideración de ruta (relativa/absoluta) en el copy
código fuente, el src
La variable se pasa directamente como argumento de copyfile
.
def copy(src, dst):
"""Copy data and mode bits ("cp src dst").
The destination may be a directory.
"""
if os.path.isdir(dst):
dst = os.path.join(dst, os.path.basename(src))
copyfile(src, dst)
copymode(src, dst)