python - 从本地 linux 文件夹移动到使用 cifs 挂载的 windows 共享

标签 python linux windows file-io share

我需要将脚本中的文件从 ext4 硬盘上的本地文件夹移动到 Windows 共享文件夹,如下所示:mount -t cifs -o username=username,password=password,rw,nounix ,iocharset=utf8,file_mode=0777,dir_mode=0777//192.168.1.120/storage/mnt/storage

我尝试使用 os.rename(src,dst)shutil.move(src,dst) 甚至 subprocess.call(['mv ', src,dst], Shell=True)subprocess.call(['mv', src,dst])

获取每个文件的错误以及由于 linux 文件所有权/权限我可以告诉它的错误..

例如当 mv/mnt/networkshare/file1.txt/tmp/file1.txt 没问题,但是

mv /tmp/file1.txt /mnt/networkshare/file1.txt

结果

"mv: preserving times for /mnt/networkshare/file1.txt: Operation not permitted"
"mv preserving permissions for /mnt/networkshare/file1.txt: Operation not permitted"

我假设 os.rename(src,dst)shutil.move(src,dst) 也会出现同样的问题,但它们并不那么健谈。

shutil.move(src,dst) 告诉我:[Errno 1] 不允许操作:'/mnt/networkshare/file1.txt'

os.rename(src,dst) 说:[Errno 18] 无效的跨设备链接

编辑:pcmanfm 能够很好地从本地剪切和粘贴到远程。

另外..让我感到困惑的是一些文件被移动了..

最佳答案

os.rename 无法跨文件系统移动文件,因为底层 rename syscall不允许:

rename() does not work across different mount points, even if the same filesystem is mounted on both.

至于为什么 shutil.move 失败,答案也在于 its documentation :

If the destination is on the current filesystem, then simply use rename. Otherwise, copy src (with copy2()) to the dst and then remove src.

让我们check copy2那么!

Similar to copy(), but metadata is copied as well – in fact, this is just copy() followed by copystat()

所以,失败的是 copystat - 因为它无法在这样的挂载上设置文件元数据。

因为 shutil 似乎没有不复制元数据就重命名的方法,我们必须自己做。我们来看看它的源码:

In [3]: print inspect.getsource(shutil.move)
def move(src, dst):
    """Recursively move a file or directory to another location. This is
    similar to the Unix "mv" command.

    If the destination is a directory or a symlink to a directory, the source
    is moved inside the directory. The destination path must not already
    exist.

    If the destination already exists but is not a directory, it may be
    overwritten depending on os.rename() semantics.

    If the destination is on our current filesystem, then rename() is used.
    Otherwise, src is copied to the destination and then removed.
    A lot more could be done here...  A look at a mv.c shows a lot of
    the issues this implementation glosses over.

    """
    real_dst = dst
    if os.path.isdir(dst):
        if _samefile(src, dst):
            # We might be on a case insensitive filesystem,
            # perform the rename anyway.
            os.rename(src, dst)
            return

        real_dst = os.path.join(dst, _basename(src))
        if os.path.exists(real_dst):
            raise Error, "Destination path '%s' already exists" % real_dst
    try:
        os.rename(src, real_dst)
    except OSError:
        if os.path.isdir(src):
            if _destinsrc(src, dst):
                raise Error, "Cannot move a directory '%s' into itself '%s'." % (src, dst)
            copytree(src, real_dst, symlinks=True)
            rmtree(src)
        else:
            copy2(src, real_dst)
            os.unlink(src)

看来,正如预测的那样,我们需要做的就是将copy2替换为copy。我们可以通过复制源代码并重命名函数或简单地通过

def move_without_copying_stat(src,dst):
    old= shutil.copy2
    shutil.copy2= shutil.copy
    shutil.move(src,dst)
    shutil.copy2= old

如果你今天感觉很幸运。了解 the consequences of such留给读者作为练习

关于python - 从本地 linux 文件夹移动到使用 cifs 挂载的 windows 共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26654097/

相关文章:

c++ - 在我的 C++ 程序中,所有线程都停留在 "select () from/lib64/libc.so.6",内存使用率很高

c++ - 在没有 Chrome 的情况下运行 Chrome Native Client (NaCL) 插件

python - Jupyter笔记本启动错误

Python幂律适用于使用ODR的数据中的上限和不对称错误

python - tkinter showerror 创建空白 tk 窗口

如果变量属于堆或堆栈,我可以通过 GDB 找到吗?

python - USB 设备 UDev 和 D-BUS

windows - Octave : `char(97)` doesn't show result in console 中的奇怪问题

c++ - SetTimer(带回调函数)是否通过启动一个新线程来工作?

python - 在模块和类之间进行选择