Atomic `ln -sf` in python (symlink overwriting exsting file)

后端 未结 1 1766
逝去的感伤
逝去的感伤 2021-01-24 06:26

I want create a symlink, overwriting an existing file or symlink if needed.

I\'ve discovered that os.path.exists only returns True for non-broken symlinks,

1条回答
  •  北恋
    北恋 (楼主)
    2021-01-24 07:03

    This code tries to minimise the possibilities for race conditions:

    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
    

    Note:

    1. If the function is interrupted (e.g. computer crashes), an additional random link to the target might exist.

    2. An unlikely race condition still remains: the symlink created at the randomly-named temp_link_name could be modified by another process before replacing link_name.

    I raised a python issue to highlight the issues of os.symlink() requiring the target not exist.

    Credit to Robert Seimer's input.

    0 讨论(0)
提交回复
热议问题