43 votes

Remplacer les liens symboliques par des fichiers

Y a-t-il un moyen facile de remplacer tous les liens symboliques par le fichier auquel ils se lient ?

26voto

RedX Points 391

Si j'ai bien compris, le drapeau -L de la commande cp devrait faire exactement ce que vous voulez.

Il vous suffit de copier tous les liens symboliques et ils seront remplacés par les fichiers auxquels ils pointent.

cp -L fichiers tmp/ && rm fichiers && mv tmp/fichiers .

20voto

James Mertz Points 390

Pour certaines définitions de "facile" :

#!/bin/sh
set -e
for link; do
    test -h "$link" || continue

    dir=$(dirname "$link")
    reltarget=$(readlink "$link")
    case $reltarget in
        /*) abstarget=$reltarget;;
        *)  abstarget=$dir/$reltarget;;
    esac

    rm -fv "$link"
    cp -afv "$abstarget" "$link" || {
        # en cas d'échec, restaurer le lien symbolique
        rm -rfv "$link"
        ln -sfv "$reltarget" "$link"
    }
done

Exécutez ce script avec les noms de lien en argument, par exemple avec find . -type l -exec /chemin/vers/script {} +

19voto

TheAlbear Points 2324

Pourrait être plus facile d'utiliser tar pour copier les données dans un nouveau répertoire.

-H      (mode c et r seulement) Les liens symboliques mentionnés en ligne de commande seront
        suivis; la cible du lien sera archivée, pas le
        lien lui-même.

Vous pourriez utiliser quelque chose comme ceci

tar -hcf - sourcedir | tar -xf - -C newdir

tar --help:
-H, --format=FORMAT        crée une archive du format donné
-h, --dereference          suivre les liens symboliques; archiver et extraire les fichiers vers lesquels ils pointent

6voto

James T Snell Points 5866

« Facile » sera probablement une fonction de vous.

Je écrirais probablement un script qui utilise l'utilitaire en ligne de commande « find » pour trouver des fichiers liés symboliquement, puis appelle rm et cp pour supprimer et remplacer le fichier. Vous feriez probablement bien également de vérifier que l'action appelée par find vérifie s'il reste suffisamment d'espace libre avant de déplacer le lien symbolique.

Une autre solution pourrait être de monter le système de fichiers en question via quelque chose qui masque les liens symboliques (comme Samba), puis simplement copier tout à partir de là. Mais dans de nombreux cas, quelque chose comme cela introduirait d'autres problèmes.

Une réponse plus directe à votre question est probablement « oui ».

Edit : Selon la page de manuel de find, cette commande listera tous les fichiers liés symboliquement jusqu'à une profondeur de 2 répertoires, à partir de / :

find / -maxdepth 2 -type l -print

(trouvé ici)

Pour que find exécute quelque chose lorsqu'il trouve quelque chose :

find / -maxdepth 2 -type l -exec ./ReplaceSymLink.sh {} \;

Je crois que cela appellera un script que je viens d'inventer, et transmettra le nom du fichier que vous venez de trouver. Sinon, vous pouvez capturer la sortie de find dans un fichier (utilisez "find [blah] > symlinks.data", etc) puis transmettez ce fichier à un script que vous avez écrit pour gérer la copie de l'original de manière élégante.

4voto

MastroGeppetto Points 141

Ceci est la ligne de commande que j'ai utilisée : supposez que tous les fichiers locaux sont des liens vers un autre fichier dans "source". Vous pouvez affiner la sélection des fichiers avec des motifs ou "find". S'il vous plaît, comprenez avant d'utiliser.

for f in *; do cp --remove-destination source/$f $f; done

J'espère que cela vous aide

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X