如果符号链接已经存在,如何覆盖Python3中的现有符号链接?

问题描述

我有一个工作正常的 bash 脚本,它创建和/或将当前的符号链接重写为新路径,而没有任何数据争用。如果程序尝试查找路径,则它将从符号链接获取旧路径或新路径。这是由于 -f模式而起作用的。这是 bash 的外观:

cd /srv/
ln -nsf /home/myproject/video123.ts latest_video.mkv
ln -nsf /home/myproject/video124.ts latest_video.mkv
ln -nsf /home/myproject/video125.ts latest_video.mkv

python3中,有一个名为 os.symlink()的模块,该模块创建符号链接,但无法实现替代行为。

import os,errno

def symlink_force(target,link_name):
    try:
        os.symlink(target,link_name)
    except OSError,e:
        if e.errno == errno.EEXIST:
            os.remove(link_name)
            os.symlink(target,link_name)
        else:
            raise e

您可以看到,在很短的时间内会有停机时间,调用 os.remove(link_name)方法。关于如何在不删除现有符号链接的情况下进行覆盖的想法?

任何帮助表示赞赏。

解决方法

查看ln -nsf(带有strace)的行为将显示该命令由2个系统调用执行:

  • 在目标文件夹中使用临时文件名在源文件中创建符号链接。
  • 将临时文件重命名为目标文件

此方法(相对于remove / symlink)的优点在于,重命名可确保在任何时间目标文件都指向旧文件或新文件。

可能的Python实现(假设可以安全地使用“ .new”作为临时链接)

def symlink_force(target,link_name):
    try:
       temp_link = link_name + ".new"
       os.remove(temp_link)
       os.symlink(target,temp_link)
       os.rename(temp_link,link_name)
    except OSError e:
       # Handle critical errors