【问题标题】:How to override existing symlink in Python3 if symlink already exists?如果符号链接已经存在,如何覆盖 Python3 中的现有符号链接?
【发布时间】:2020-08-31 08:27:07
【问题描述】:

我有一个有效的 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) 方法时会出现停机时间。关于如何在不删除现有符号链接的情况下进行覆盖的任何想法?

任何帮助表示赞赏。

【问题讨论】:

    标签: python-3.x bash symlink data-race


    【解决方案1】:

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

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

    这种方法(相对于删除/符号链接)的优点是重命名保证在任何时间点,目标文件都将指向旧文件或新文件。

    可能的 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
    
    

    【讨论】:

      猜你喜欢
      • 2021-06-10
      • 1970-01-01
      • 2012-10-16
      • 1970-01-01
      • 2011-07-12
      • 1970-01-01
      • 2016-03-17
      • 2019-01-08
      相关资源
      最近更新 更多