Python Shutil.copy не работает в файловых системах FAT (Ubuntu)
Вопрос
Проблема:Использование Shutil.copy() для копирования файла в смонтированную файловую систему FAT16 в Linux завершается неудачно (Python 2.7.x).Ошибка связана с внутренней ошибкой Shutil и фактическим сбоем в файле Shutil.chmod, который, похоже, выполняет Shutil.copy.
Shell chmod также не работает, поскольку разрешения не поддерживаются в FAT.
Вопросы:Есть ли какой-нибудь аккуратный способ обойти это?Я знаю, что у меня есть несколько вариантов, например:
- Использовать файл копирования — не идеально, поскольку для этого требуется полный путь, а не только целевой каталог, но выполнимо.
- Выполните оболочку cp для копирования файлов
- Напишите собственную функцию копирования, которая не пытается изменить режимы файлов.
Есть ли способ обойти это в Python ИЛИ в параметрах монтирования FAT?Теперь я монтирую файловую систему внутри своей программы, выполнив команду mount -t vfat -o umask=000 /dev/loop0 /mnt/foo.
Перехват исключения не помогает, поскольку исключение происходит внутри Shutil.copy, а метод Shutil.copy(), похоже, удаляет целевой файл, когда он перехватывает IOException из Shutil.chmod(), прежде чем передать IOException вызывающей функции.
Есть идеи, или мне просто выбрать один из 1-3?
Ханну
Решение
Ну я обманываю в этом случае.
Если я знаю, что цель - это файловая система, в которой работает chmod
, я просто удаляю метод chmod
из пакета ОС с использованием del os.chmod
, и это позволяет копию добиться успеха.
>>> import os
>>> print hasattr(os, 'chmod')
True
>>> foo = os.chmod
>>> del os.chmod
>>> print hasattr(os, 'chmod')
False
.
Теперь теперь позволяет выполнять копию без выхода из строя на CHMOD.Затем мы повторно включаем это, назначая атрибут обратно.
>>> setattr(os, 'chmod', foo)
>>> print hasattr(os, 'chmod')
True
. Другие советы
Использовать shutil.copyfile
, для него не требуется полный путь.
Удаление os.chmod
во всем мире это нет хорошая идея.
$ 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 ./
Как вы можете видеть в исходном коде Shutil на Python (/usr/lib/python2.7/shutil.py
), нет никакого рассмотрения пути (относительного/абсолютного) в copy
исходный код, src
переменная передается напрямую в качестве аргумента 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)