使用Python递归创建硬链接

18

我想要做的基本上是 cp -Rl dir1 dir2。但据我了解,Python 只提供了 shutils.copytree(src,dst),它实际上复制文件,但没有硬链接文件的可能性。

我知道可以使用 subprocess 模块调用 cp 命令,但我更愿意找到一种更干净(Pythonic)的方法来实现。

那么有没有简单的方法来实现这个目标,还是我必须递归地实现它呢?


目录遍历非常容易,为什么不试试呢? - Blender
5
这并不是关于尝试或者不尝试的问题:这个问题更想表达的是:“我无法想象这没有被做过数百次,因此肯定有在模块xy中可用的解决方案。”一直重复造轮子似乎不太合适。 - devsnd
2个回答

28
可以在Python标准库中使用shutilos.link来实现:
import os, shutil

shutil.copytree(src, dst, copy_function=os.link)

1
正如我所说,我不想使用subprocess模块。这也意味着我不想使用os.system调用,因为它比subprocess给我的控制更少。特别是因为os.system可能会悄悄失败。 - devsnd
1
@twall:请注意,这仅适用于Python 3。在Python 2中,您可能需要修改示例代码:http://docs.python.org/library/shutil.html#copytree-example - Kabie
1
啊,太好了!我已经使用了Damian Ayers的示例并根据我的需求进行了修改,但这实际上是我想到的解决方案。(我应该在查看shutil源代码之前就这样做...)谢谢! - devsnd
我知道这已经过去很多年了,但我想说的是,“os.system”建议并不是一个好的建议。`cp -l'不是标准的命令。GNU cp和FreeBSD cp都支持它,但它并不是必需的,因此在任何脚本中使用它都不是一个好主意。 - Roflcopter4
从Python文档中并不清楚copy_function=os.link是否真的存在,或者需要人工创建。(请参阅链接文档中的示例。)如果它确实存在,则os.symlink也应该是可能的。 - not2qubit
一般来说,在Python中,os.system是一个糟糕的解决方案,应该避免使用。感谢shutil版本。 - sauerburger

7

这是一个纯Python的复制函数,应该与cp -Rl src dst的操作相同。

import os
from os.path import join, abspath

def hardcopy(src, dst):
    working_dir = os.getcwd()
    dest = abspath(dst)
    os.mkdir(dst)
    os.chdir(src)
    for root, dirs, files in os.walk('.'):
        curdest = join(dst, root)
        for d in dirs:
            os.mkdir(join(curdst, d))
        for f in files:
            fromfile = join(root, f)
            to = join(curdst, f)
            os.link(fromfile, to)
    os.chdir(working_dir)

很抱歉不接受你的答案,但是另一个答案确实是那个问题的正确答案,尽管你的答案也解决了这个问题。再次感谢。 - devsnd
没关系。我还没有仔细研究过Python 3,但如果您使用的是它,那么这是一个更好的解决方案。 :) - Damien Ayers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接