2017-02-27 2 views
0

Considérons une fonction simple pour créer un répertoire, puis un lien symbolique vers le répertoire, tous requis pour être supposés sous le répertoire de travail courant. Dans le cas où le répertoire et le lien sont directement dans le répertoire de travail en cours, ce processus réussit. Mais lorsque le répertoire et le lien sont imbriqués plus loin, la création du répertoire réussit, tandis que le lien symbolique créé est rompu et pointe vers un chemin incorrect.Comment créer un lien symbolique en Python en utilisant uniquement des chemins relatifs

In [1]: def make_dir_and_symlink(dir_relative_to_cwd, sym_relative_to_cwd): 
    ...:  os.mkdir(dir_relative_to_cwd) 
    ...:  os.symlink(dir_relative_to_cwd, sym_relative_to_cwd) 
    ...:  

In [2]: make_dir_and_symlink("test", "test-link") 

In [3]: os.path.exists("test") 
Out[3]: True 

In [4]: os.path.exists("test-link") 
Out[4]: True 

In [5]: make_dir_and_symlink("test/other-test", "test/other-test-link") 

In [6]: os.path.exists("test/other-test") 
Out[6]: True 

In [7]: os.path.exists("test/other-test-link") 
Out[7]: False 

Sans avoir recours à des chemins absolus dans le second exemple, comment puis-je créer un lien symbolique quelque part dans un chemin qui est relatif au répertoire de travail actuel?

Répondre

0

Il semble que cela peut être réalisé pour une situation limitée en combinant os.path.relpath et os.path.basename:

def make_dir_and_symlink(dir_relative_to_cwd, sym_relative_to_cwd): 
    os.mkdir(dir_relative_to_cwd) 
    target_name = os.path.basename(
     os.path.relpath(dir_relative_to_cwd, sym_relative_to_cwd) 
    ) 
    os.symlink(target_name, sym_relative_to_cwd) 



In [1]: def make_dir_and_symlink(dir_relative_to_cwd, sym_relative_to_cwd): 
    ...:  os.mkdir(dir_relative_to_cwd) 
    ...:  os.symlink(os.path.basename(os.path.relpath(dir_relative_to_cwd, sym_relative_to_cwd)), sym_relative_to_cwd) 
    ...:  

In [2]: make_dir_and_symlink("test", "test-link") 

In [3]: os.path.exists("test") 
Out[3]: True 

In [4]: os.path.exists("test-link") 
Out[4]: True 

In [5]: make_dir_and_symlink("test/other-test", "test/other-test-link") 

In [6]: os.path.exists("test/other-test") 
Out[6]: True 

In [7]: os.path.exists("test/other-test-link") 
Out[7]: True 

Ce ne devrait pas traiter le cas général lorsque l'emplacement symlink peut être arbitraire par rapport à l'emplacement cible. os.path.basename ne renverra que le composant de base immédiat du nom de chemin d'accès, de sorte qu'il fonctionne dans cette situation car il est en outre supposé que la cible et son lien symbolique se trouvent côte à côte dans l'arborescence à partir du répertoire de travail actuel.

Une solution qui ne nécessite pas la résolution de chemins absolus, mais qui laisse toujours le nom de lien être arbitraire dans le répertoire de travail actuel par rapport au nom de la cible est très précieuse.