Атомный `ln -sf` в python (символьная ссылка перезаписывает файл exsting) - PullRequest
0 голосов
/ 18 апреля 2019

Я хочу создать символическую ссылку, перезаписав существующий файл или символическую ссылку, если необходимо.

Я обнаружил, что os.path.exists возвращает только True для неразрывных символических ссылок, поэтому я предполагаю, что любой тест должен также включать os.path.lexists.

Какой самый атомарный способ реализовать ln -sf в python? (То есть предотвращение создания файла другим процессом между удалением и созданием символической ссылки)


Дифференциация: В этом вопросе не указано атомное требование

1 Ответ

0 голосов
/ 18 апреля 2019

Этот код пытается минимизировать возможности для условий гонки:

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.

Я поднял проблему с питоном , чтобы выделить проблемы os.symlink(), требующие, чтобы цель не существовала.

Кредит Роберт Сеймер .

...