Y a-t-il un moyen facile de remplacer tous les liens symboliques par le fichier auquel ils se lient ?
Réponses
Trop de publicités?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 {} +
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
« 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
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.
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
- Réponses précédentes
- Plus de réponses