在 Python 中复制符号链接 [英] Copying a symbolic link in Python

查看:34
本文介绍了在 Python 中复制符号链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想复制一个文件 src 到目标 dst,但如果 src 恰好是一个符号链接,则保留该链接复制文件的内容.执行复制后,os.readlink 应该为 srcdst 返回相同的值.

shutil 模块有几个函数,如copyfilecopycopy2,但所有这些将复制文件的内容,并且不会保留链接.shutil.move 具有正确的行为,除了删除原始文件的事实.

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

解决方案

Python 3 follow_symlinks

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

例如对于 shutil.copy:

shutil.copy(src, dest, follow_symlinks=False)

文档说:

<块引用>

shutil.copy(src, dst, *, follow_symlinks=True)

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

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

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

FileExistsError: [Errno 17] 文件存在:'b' ->'C'

与成功覆盖的 follow_symlinks=True 不同.

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

#!/usr/bin/env python3进口商铺导入操作系统定义复制(src,dst):如果 os.path.islink(src):如果 os.path.lexists(dst):os.unlink(dst)linkto = os.readlink(src)os.symlink(linkto, dst)别的:关闭.copy(src, dst)如果 __name__ == '__main__':os.symlink('c', 'b')os.symlink('b', 'a')复制('a','b')with open('c', 'w') as f:f.write('a')打开('d','w'):经过复制('c','d')复制('a','c')

在 Ubuntu 18.10、Python 3.6.7 中测试.

I want to copy a file src to the destination dst, but if src happens to be a symbolic link, preserve the link instead of copying the contents of the file. After the copy is performed, os.readlink should return the same for both src and dst.

The module shutil has several functions, such as copyfile, copy and copy2, but all of these will copy the contents of the file, and will not preserve the link. shutil.move has the correct behavior, other than the fact it removes the original file.

Is there a built-in way in Python to perform a file copy while preserving symlinks?

解决方案

Python 3 follow_symlinks

In Python 3, most copy methods of shutil have learned the follow_symlinks argument, which preserves symlinks if selected.

E.g. for shutil.copy:

shutil.copy(src, dest, follow_symlinks=False)

and the docs say:

shutil.copy(src, dst, *, follow_symlinks=True)

Copies the file src to the file or directory dst. src and dst should be strings. If dst specifies a directory, the file will be copied into dst using the base filename from src. Returns the path to the newly created file.

If follow_symlinks is false, and src is a symbolic link, dst will be created as a symbolic link. If follow_symlinks` is true and src is a symbolic link, dst will be a copy of the file src refers to.

This has one problem however: if you try to overwrite an existing file or symlink, it fails with:

FileExistsError: [Errno 17] File exists: 'b' -> 'c'

unlike the follow_symlinks=True which successfully overwrites.

The same also happens for os.symlink, so I ended up using instead:

#!/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')

Tested in Ubuntu 18.10, Python 3.6.7.

这篇关于在 Python 中复制符号链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆