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

jv4diomz  于 2023-06-29  发布在  Linux
关注(0)|答案(2)|浏览(174)

我需要将脚本中的文件从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)告诉我:[错误1]不允许操作:'/mnt/networkshare/file1.txt'
os.rename(src,dst)说道:[Errno 18]无效的跨设备链接
编辑:pcmanfm是能够剪切和粘贴从本地到远程刚刚好.
另外..让我困惑的是有些文件被移动了..

yizd12fk

yizd12fk1#

os.rename不能跨文件系统移动文件,因为底层的rename syscall不允许这样做:
rename()不能跨不同的挂载点工作,即使同一个文件系统挂载在两个挂载点上。
至于shutil.move为什么会失败,答案也在它的文档中:
如果目标在当前文件系统上,那么只需使用rename。否则,复制src(使用copy 2())到dst,然后删除src。
我们来看看copy2
与copy()类似,但也复制元数据-实际上,这只是copy()后跟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)

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

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

如果你今天运气好的话理解这样做的后果是留给读者的练习

blmhpbnm

blmhpbnm2#

从python 3.5版本开始,你可以调用:

shutil.move(src, dst, copy_function=shutil.copyfile)

shutil.copyfile仅复制文件内容,不保留权限和元数据

相关问题