python中的ln -sf(符号链接覆盖现有文件)

时间:2019-04-18 06:40:41

标签: python atomic symlink

我想创建一个符号链接,如果需要,可以覆盖现有文件或符号链接。

我发现os.path.exists对于不中断的符号链接仅返回True,因此我猜测任何测试还必须包括os.path.lexists

在python中实现ln -sf的最原子的方法是什么? (即,防止在删除和符号链接创建之间由另一个进程创建文件)


区别:This question没有指定原子要求

1 个答案:

答案 0 :(得分:0)

此代码试图将竞争条件的可能性降至最低:

import os
import tempfile

def symlink_force(target, link_name):
    '''
    Create a symbolic link link_name pointing to target.
    Overwrites link_name if it exists.
    '''

    # os.replace() may fail if files are on different filesystems
    link_dir = os.path.dirname(link_name)

    while True:
        temp_link_name = tempfile.mktemp(dir=link_dir)
        try:
            os.symlink(target, temp_link_name)
            break
        except FileExistsError:
            pass
    try:
        os.replace(temp_link_name, link_name)
    except OSError:  # e.g. permission denied
        os.remove(temp_link_name)
        raise

注意:

  1. 如果功能中断(例如计算机崩溃),则可能存在指向目标的其他随机链接。

  2. 仍然存在不太可能出现的竞争状况:在替换temp_link_name之前,可以用另一个进程修改在随机命名的link_name上创建的符号链接。

我提出了python issue来强调os.symlink()要求目标不存在的问题。

贷记到Robert Seimer's input