GNU/Linux >> Tutoriels Linux >  >> Linux

`os.symlink` vs `ln -s`

os.symlink crée un seul lien symbolique.

ln -s crée plusieurs liens symboliques (si son dernier argument est un répertoire et qu'il existe plusieurs sources). L'équivalent Python est quelque chose comme :

dst = args[-1]
for src in args[:-1]:
    os.symlink(src, os.path.join(dst, os.path.dirname(src)))

Alors, comment ça marche quand vous faites ln -s /home/guest/dir1/* /home/guest/dir2/ ? Votre coque fait que cela fonctionne, en transformant le caractère générique en plusieurs arguments. Si vous deviez juste exec le ln commande avec un caractère générique, il rechercherait une seule source littéralement nommée * en /home/guest/dir1/ , pas tous les fichiers de ce répertoire.

L'équivalent Python est quelque chose comme (si cela ne vous dérange pas de mélanger deux niveaux et d'ignorer beaucoup d'autres cas - tildes, variables env, substitution de commande, etc. qui sont possibles au niveau du shell) :

dst = args[-1]
for srcglob in args[:-1]:
    for src in glob.glob(srcglob):
        os.symlink(src, os.path.join(dst, os.path.dirname(src)))

Vous ne pouvez pas faire cela avec os.symlink seul - soit une partie de celui-ci - parce qu'il ne le fait pas. C'est comme dire "Je veux faire l'équivalent de find . -name foo en utilisant os.walk sans filtrer sur le nom." Ou, d'ailleurs, je veux faire l'équivalent de ln -s /home/guest/dir1/* /home/guest/dir2/ sans que le shell ne me submerge."

La bonne réponse est d'utiliser glob , ou fnmatch , ou os.listdir plus une expression régulière, ou ce que vous préférez.

Ne pas utilisez os.walk , car cela fait un récursif marche du système de fichiers, donc ce n'est même pas proche du shell * extension.


* est un modèle d'extension de shell, qui dans votre cas désigne "tous les fichiers commençant par /home/guest/dir1/ ".

Mais c'est le rôle de votre shell d'étendre ce modèle aux fichiers auxquels il correspond. Pas le ln commande.

Mais os.symlink n'est pas un shell, c'est un appel au système d'exploitation - par conséquent, il ne prend pas en charge les modèles d'extension du shell. Vous devrez faire ce travail dans votre script.

Pour ce faire, vous pouvez utiliser os.walk , ou os.listdir . Comme indiqué dans l'autre réponse, l'appel approprié dépendra de ce que vous voulez faire. (os.walk ne serait pas l'équivalent de * )

Pour vous en convaincre :lancez cette commande sur une machine Unix dans votre terminal :python -c "import sys; print sys.argv" * . Vous verrez que c'est le shell qui fait la correspondance.


Linux
  1. Expiration du délai dans un script shell ?

  2. Sur quel shell suis-je en cours d'exécution ?

  3. Tableaux associatifs dans les scripts shell ?

  4. Verrouiller correctement les scripts Shell ?

  5. Histoire mutilée ?

Interface de commandes

Qu'est-ce que le shell de connexion sous Linux ?

Tutoriel étape par étape sur les scripts shell

Tableaux dans les scripts shell

8 types de shells Linux

Qu'est-ce qu'un fichier .sh ?