web-dev-qa-db-fra.com

Comment puis-je "relier" un grand nombre de liens symboliques cassés?

J'ai une arborescence de répertoires qui a un tas de liens symboliques vers des fichiers sous /home... cependant, j'ai déménagé /home à /mnt/home et besoin d'un moyen de "relier" tous les liens symboliques. Une telle fonctionnalité existe-t-elle ou dois-je écrire un script pour le faire?

À titre d'exemple, j'ai quelque chose comme ceci:

[root@trees ~]# ls -l /mnt/home/someone/something
total 4264
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 a -> /home/someone/someotherthing/a
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 b -> /home/someone/someotherthing/b
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 c -> /home/someone/someotherthing/c
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 d -> /home/someone/someotherthing/d
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 e -> /home/someone/someotherthing/e

/mnt/home/someone/something/subdir:
total 4264
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 a -> /home/someone/someotherthing/subdir/a
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 b -> /home/someone/someotherthing/subdir/b
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 c -> /home/someone/someotherthing/subdir/c
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 d -> /home/someone/someotherthing/subdir/d
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 e -> /home/someone/someotherthing/subdir/e

Je veux une commande qui trouvera tous les liens symboliques et les reliera aux mêmes endroits mais en dessous /mnt/home au lieu de /home

Une telle commande existe-t-elle?

55
Josh

Il n'y a pas de commande pour recibler un lien symbolique, tout ce que vous pouvez faire est de le supprimer et d'en créer un autre. En supposant que vous ayez GNU utilitaires (par exemple sous Linux non intégré ou Cygwin), vous pouvez utiliser le -lname primaire de find pour faire correspondre les liens symboliques par leur cible, et readlink pour lire le contenu du lien. Non testé:

find /mnt/home/someone/something -lname '/home/someone/*' \
     -exec sh -c 'ln -snf "/mnt$(readlink "$0")" "$0"' {} \;

Il serait préférable de relativiser ces liens symboliques. Il existe un petit utilitaire pratique appelé symlinks (à l'origine par Mark Lords, maintenant maintenu par J. Brandt Buckley), présent dans de nombreuses distributions Linux. Avant le déplacement ou après avoir restauré les liens valides comme ci-dessus, exécutez symlinks -c /mnt/home/someone/something pour convertir tous les liens symboliques absolus sous le répertoire spécifié en liens symboliques relatifs à moins qu'ils ne traversent une frontière de système de fichiers.

Je sais que ce n'est pas exactement ce que l'auteur demande, mais il semble qu'ils aient déjà leur réponse, alors j'ajoute ceci pour d'autres comme moi qui tombent sur la question.

Ce qui suit devrait aider si une solution plus flexible est nécessaire, comme avoir un tas de liens symboliques rompus qui peuvent être corrigés en remplaçant une partie des cibles du lien symbolique.

par exemple. Après un changement de nom d'utilisateur, pour remplacer l'ancien nom d'utilisateur par le nouveau nom d'utilisateur dans la cible de nombreux liens, une fois le déplacement effectué. Créez un script appelé replace-simlinks illustré ci-dessous:

#!/bin/bash
link=$1
# grab the target of the old link
target=$(readlink -- "$1")

# replace the first occurrence of oldusername with newusername in the target string
target=${target/oldusername/newusername}

# Test the link creation
echo ln -s -- "$target" "$link"

# If the above echo shows the correct commands are being issued, then uncomment the following lines and run the command again
#rm "$link"
#ln -s "$target" "$link"

et appelez-le avec la commande suivante:

find /home/newusername/ -lname '/home/oldusername/*' -exec ~/bin/replace-simlinks {} \;

J'espère que cela aide quelqu'un

edit: Merci Gilles pour le kickstart sur ce script et le conseil sur l'utilisation du script symlinks pour rendre les liens relatifs.

13
Gerry

Créer /home comme lien symbolique vers /mnt/home, et tous les liens symboliques existants seront à nouveau valides.

4
Keith Thompson