Convertir un lien fixe en un lien symbolique

Il est facile de convertir un lien symbolique en un lien avec ln -f ( exemple )

Il serait également facile de convertir un hardlink ( link noms de files et original ) en un lien symbolique vers link->original dans le cas où vous connaissez les deux files et définissez vous-même lequel est le «file original». Vous pourriez facilement créer un script simple convert-known-hardlink-to-symlink qui se traduirait par quelque chose comme:

 convert-known-hardlink-to-symlink link original $ ls -li 3802465 lrwxrwxrwx 1 14 Dec 6 09:52 link -> original 3802269 -rw-rw-r-- 1 0 Dec 6 09:52 original 

Mais ce serait vraiment utile si vous aviez un script où vous pourriez définir un directory de travail (par défaut ./ ) et un directory de search où searchr (par défaut / ) pour les files avec le même inode, puis convertir tous ces liens liens symboliques.

Le résultat serait que dans le directory de travail défini, tous les files qui sont des liens physiques sont remplacés par des liens symboliques vers le premier file trouvé avec le même inode à la place.


Un début serait find . -type f -links +1 -printf "%i: %p (%n)\n" find . -type f -links +1 -printf "%i: %p (%n)\n"

    J'ai créé un script qui va le faire. Le script convertit tous les liens physiques qu'il trouve dans un directory source (premier argument) qui sont les mêmes que dans le directory de travail (second argument optionnel) en liens symboliques:

    https://gist.github.com/rubo77/7a9a83695a28412abbcd

    Il a une option -n pour une course à sec, qui ne fait rien mais montre ce qui serait fait.

    Partie principale:

     $WORKING_DIR=./ #relative source directory from working directory: $SOURCE_DIR=../otherdir/with/hard-links/with-the-same-inodes # find all files in WORKING_DIR cd "$WORKING_DIR" find "." -type f -links +1 -printf "%i %p\n" | \ while read working_inode working_on do find "$SOURCE_DIR" -type f -links +1 -printf "%i %p\n" | sort -nk1 | \ while read inode file do if [[ $inode == $working_inode ]]; then ln -vsf "$file" "$working_on" fi done done 

    Les -liens +1 -> Trouveront tous les files qui ont PLUS d'un lien. Les files avec liens hypertext ont un nombre de liens d'au less deux.

    Au less GNU find vous permet également de searchr par Inode, soit numérique ( -inode ) soit en spécifiant le lien ( -samefile ).

    Donc, vous pourriez utiliser:

     find "$WORKING_DIR" -type f -links +1 | while read file do find "$SOURCE_DIR" -samefile "$file" -exec ln -vsf '{}' "$file" \; done 

    Vous devez juste vous assurer d'utiliser des directorys séparés. D'autre part, je me plaindrais si vous essayiez de lier un file en lui-même.

    En outre, vous devez soit fournir un path absolu pour $SOURCE_DIR , soit utiliser l'option -r avec ln pour créer des liens relatifs, sinon les liens risquent d'être rompus.

    Ce n'est pas impossible, mais comme @tkausl l'a suggéré, cela implique de faire une search sur toute la partition, à less d'avoir une autre connaissance des locations possibles.

    S'il y a plus de 2 liens vers le file, il n'y a aucun moyen d'identifier le file "original".

    J'ai écrit des programmes pour find tous les liens qui ont la même cible. Ce n'est certainement pas une tâche à faire dans un script simple.