gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 09:24:21 25 4
gpt4 key购买 nike

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

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com