Атомный `ln -sf` в python (символьная ссылка перезаписывает файл exsting)
Я хочу создать символическую ссылку, перезаписывая существующий файл или символическую ссылку, если это необходимо.
Я обнаружил, что os.path.exists
только возвращается True
для неразрывных символических ссылок, так что я предполагаю, что любой тест должен также включать os.path.lexists
,
Какой самый атомарный способ реализовать ln -sf
в питоне? (То есть предотвращение создания файла другим процессом между удалением и созданием символической ссылки)
Дифференциация: в этом вопросе не указано атомарное требование
1 ответ
Этот код пытается минимизировать возможности для условий гонки:
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
Замечания:
Если функция прервана (например, сбой компьютера), может существовать дополнительная случайная ссылка на цель.
Остается маловероятное состояние гонки: символическая ссылка, созданная по случайному имени
temp_link_name
может быть изменен другим процессом перед заменойlink_name
,
Я поднял вопрос о питоне, чтобы выделить проблемы os.symlink()
Требование цели не существует.