在Python中复制符号链接

dav*_*idg 24 python symlink

我想将文件复制src到目标dst,但如果src恰好是符号链接,请保留链接而不是复制文件的内容.进行复制后,os.readlink应返回两个相同的srcdst.

该模块shutil具有多个功能,例如copyfile,copycopy2,但是所有这些功能都将复制文件的内容,并且不会保留链接.shutil.move具有正确的行为,除了它删除原始文件的事实.

在保留符号链接的同时,Python中是否有内置的方法来执行文件复制?

Joc*_*zel 44

做就是了

def copy(src, dst):
    if os.path.islink(src):
        linkto = os.readlink(src)
        os.symlink(linkto, dst)
    else:
        shutil.copy(src,dst)
Run Code Online (Sandbox Code Playgroud)

shutil.copytree做了类似的事情,但正如发送者指出的那样,只复制目录而不是单个文件是挑剔的.

  • 如果您希望将符号链接保留在目标目录中,则调用“shutil.copytree(src, dst, symlinks=True)”非常重要。 (3认同)
  • 它认为没有用于复制文件的专用函数(而不是像copytree这样的目录)保留符号链接而不是解析它们,这很奇怪,但我找不到任何一个.看来这是唯一的方法...... (2认同)

Cir*_*四事件 6

蟒蛇 3 follow_symlinks

在 Python 3 中,大多数复制方法shutil都学习了follow_symlinks参数,如果选择它会保留符号链接。

例如shutil.copy

shutil.copy(src, dest, follow_symlinks=False)
Run Code Online (Sandbox Code Playgroud)

文档说

shutil.copy(src, dst, *, follow_symlinks=True)
Run Code Online (Sandbox Code Playgroud)

将文件 src 复制到文件或目录 dst。src 和 dst 应该是字符串。如果 dst 指定了一个目录,该文件将使用来自 src 的基本文件名复制到 dst 中。返回新创建文件的路径。

如果follow_symlinks为 false,并且 src 是符号链接,则 dst 将被创建为符号链接。如果 follow_symlinks` 为真并且 src 是符号链接,则 dst 将是 src 所指文件的副本。

但是,这有一个问题:如果您尝试覆盖现有文件或符号链接,则会失败:

FileExistsError: [Errno 17] File exists: 'b' -> 'c'
Run Code Online (Sandbox Code Playgroud)

follow_symlinks=True成功覆盖的不同。

也发生了同样的情况os.symlink,所以我最终改为使用:

#!/usr/bin/env python3

import shutil
import os

def copy(src, dst):
    if os.path.islink(src):
        if os.path.lexists(dst):
            os.unlink(dst)
        linkto = os.readlink(src)
        os.symlink(linkto, dst)
    else:
        shutil.copy(src, dst)

if __name__ == '__main__':
    os.symlink('c', 'b')
    os.symlink('b', 'a')
    copy('a', 'b')

    with open('c', 'w') as f:
        f.write('a')
    with open('d', 'w'):
        pass
    copy('c', 'd')
    copy('a', 'c')
Run Code Online (Sandbox Code Playgroud)

在 Ubuntu 18.10、Python 3.6.7 中测试。