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

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

我需要将脚本中的文件从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共享

基础教程推荐