Python shutil.move: 奇怪的软链接
我写了一个脚本,目的是把旧位置的每天的文件夹移动到新位置,结构大概是这样的:
/old/YYYY/MM/DD
/new/YYYY/MM/DD
另外,我在新位置创建了一个软链接,跟移动数据没关系(这是我犯的第一个错误):
/new/2011/09 -> /old/2011/09
我的脚本主要用了这个函数调用:
for d in os.listdir("/old/2011/09"):
shutil.move(os.path.join("/old/2011/09/", d), os.path.join("/new/2011/09", d))
运行完脚本后,2011/09这个文件夹在两个地方都是空的。我在工作中也遇到过类似的情况,处理的是未归档的数据……这可真是个大问题。我想问的是,为什么shutil.move()没有给我报错,告诉我我想移动的日目录已经存在了呢? 09里面的每一天的文件夹应该是一样的,因为有软链接。
/new/2011/09/01 == /old/2011/09/01
shutil.move这个调用难道不会在调用shutil.copy2之前检查源和目标吗? 根据文档:“目标目录不能已经存在。”这是只在使用重命名的时候才这样吗?而且如果有影响的话,旧位置和新位置都是glusterfs。
感谢你能提供的任何解释。
编辑/更新:我在python-list上提了个问题,问为什么会有这样的行为,并询问是否应该改变(邮件列表存档)。他们建议我提交一个bug报告。在做测试以提交bug的过程中,我发现这个问题在Python 2.7中已经修复了。你可以在move函数的源代码中看到差异: Python 2.6 和 Python 2.7。
现在这个函数仍然可以移动/重命名,但不会神奇地删除整个目录。
1 个回答
这段话主要讲的是在 shutil.move 这个函数里的两行代码:
copytree(src, real_dst, symlinks=True)
rmtree(src)
这里的 src='old'
表示你要移动的文件夹是叫做 old
的,而 real_dst='new/old'
表示你想把它移动到一个叫 new/old
的子文件夹里。这个 copytree
命令会把 old
复制到 new/old
这个地方,这个过程是没问题的,虽然可能不是你最开始想要的结果。
接着,rmtree
命令会把 old
这个文件夹删除。这就有点麻烦了,因为此时 new
变成了一个悬空的符号链接,也就是说它指向的地方已经不存在了。