Modifier un lien symbolique en python

Comment puis-je changer de lien symbolique en point d'un fichier à un autre en Python? OS.symlink() fonction ne semble fonctionner pour créer de nouveaux liens symboliques.

22
demandé sur garsh0p 2011-11-28 20:58:53

5 réponses

Une petite fonction qui essaie de faire un lien symbolique et si elle échoue à cause d'un fichier existant, elle le supprime et se lie à nouveau.

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
19
répondu Robert Siemer 2015-10-17 00:23:20

si vous avez besoin d'une modification atomique, déverrouiller ne marchera pas.

une meilleure solution serait de créer un nouveau lien symbolique temporaire, puis de le renommer sur le lien existant:

os.symlink(target, tmpLink)
os.rename(tmpLink, linkName)

Vous pouvez assurez-vous qu'il a été mis à jour correctement:

if os.path.realpath(linkName) == target:
    # Symlink was updated

selon la documentation pour os.renommer cependant, il peut n'y avoir aucun moyen de changer atomiquement un lien symbolique dans Windows. Dans ce cas, vous ne feriez que supprimer et recréer.

18
répondu lellimecnar 2015-01-05 21:33:20

Vous pourriez os.unlink() d'abord, puis recréer avec os.symlink() pour pointer vers la nouvelle cible.

9
répondu NPE 2011-11-28 17:01:09

j'ai fait des recherches sur cette question récemment, et j'ai découvert que le meilleur moyen est en effet de unlink et symlink. Mais si vous avez juste besoin de réparer les liens rompus, par exemple avec auto-replace, alors vous pouvez faire os.readlink:

for f in os.listdir(dir):
    path = os.path.join(dir, f)
    old_link = os.readlink(path)
    new_link = old_link.replace(before, after)
    os.unlink(path)
    os.symlink(new_link, path)
7
répondu culebrón 2014-02-07 15:03:22

N'oubliez pas d'ajouter une commande de relance dans le cas où E. Erno != errno.EEXIST Vous ne voulez pas masquer une erreur alors:

if e.errno == errno.EEXIST:
     os.remove(link_name)
     os.symlink(target, link_name)
else:
    raise
1
répondu crivera 2015-08-24 10:08:06