【问题标题】:Python shutil.copy fails on FAT file systems (Ubuntu)Python shutil.copy 在 FAT 文件系统(Ubuntu)上失败
【发布时间】:2013-11-29 23:21:51
【问题描述】:

问题:在 Linux 中使用 shutil.copy() 将文件复制到 FAT16 挂载的文件系统失败(Python 2.7.x)。失败是shutil 内部错误,实际上在shutil.chmod 上失败,而shutil.copy 似乎正在执行。

Shell chmod 也会失败,因为 FAT 不支持权限。

问题:有什么巧妙的方法可以解决这个问题吗?我知道我有几个选择,例如:

  1. 使用 copyfile - 不理想,因为它需要完整路径,不仅仅是目标目录,而是可行的
  2. 执行shell cp 复制文件
  3. 编写自己的复制函数,不会尝试更改文件模式

在 Python 或 FAT 挂载选项中有没有办法解决这个问题?我现在通过执行 mount -t vfat -o umask=000 /dev/loop0 /mnt/foo 在我的程序中挂载文件系统

捕获异常并没有帮助,因为异常发生在 shutil.copy 内部,而 shutil.copy() 在从 shutil.chmod() 捕获 IOException 时似乎会删除目标文件,然后将 IOException 传递给调用函数。

有什么想法,还是我应该从 1-3 中选择一个?

汉努

【问题讨论】:

    标签: python linux mount shutil fat


    【解决方案1】:

    好吧,在这种情况下我作弊。

    如果我知道目标是chmod失败的文件系统,我只需使用del os.chmod从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
    

    【讨论】:

    • OS X 更加简洁,因为它只是忽略了 FAT/VFAT 文件系统上的 chmod,因此您无需解决此问题。
    • 效果很好。好人。实际上,我在将代码从 OSX 迁移到 Linux 时遇到了这个问题。它在 Mac 上运行良好,但在 Ubuntu 上崩溃。在这种情况下,我没有太多选择,但这似乎可以解决问题。
    【解决方案2】:

    使用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(/usr/lib/python2.7/shutil.py)的python源码中可以看到,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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-10
      • 2013-04-07
      • 2019-11-28
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 2011-11-27
      • 2017-04-14
      相关资源
      最近更新 更多