Comment remplacer / mettre à jour un lien symbolique?

188

J'essaie d'utiliser des liens symboliques. J'ai lu un peu et j'ai trouvé les commandes suivantes:

Creation -> ln -s {/path/to/file-name} {link-name}
Update -> ln -sfn {/path/to/file-name} {link-name}
Deletion -> rm {link-name}

Les créations et les suppressions fonctionnent bien. Mais les mises à jour ne fonctionnent pas. Après avoir exécuté cette commande, le lien symbolique devient invalide.

J'ai lu ici et là qu'il n'est pas possible de mettre à jour / remplacer un lien symbolique. Il y a donc des informations contradictoires sur le net. Qui a raison? Si un lien symbolique peut être mis à jour / remplacé, comment puis-je y parvenir?

Mise à jour

Voici ma structure de répertoire:

~/scripts/test/
~/scripts/test/remote_loc/
~/scripts/test/remote_loc/site1/
~/scripts/test/remote_loc/site1/stuff1.txt
~/scripts/test/remote_loc/site2/
~/scripts/test/remote_loc/site2/stuff2.txt
~/scripts/test/remote_loc/site2/
~/scripts/test/remote_loc/site3/stuff3.txt

À partir de ~/scripts/test/quand je joue:

ln -s /remote_loc/site1 test_link

a test_linkest créé, et je peux le ls -lfaire, mais il semble cassé (contrairement à ce que j'ai dit plus haut dans ma question).

Comment puis-je effectuer un lien à plusieurs niveaux de répertoire?

Jérôme Verstrynge
la source
1
Je recommande d'utiliser unlinkau lieu de rm. Avec unlinkvous ne risquez jamais de perdre des fichiers dans un répertoire source en utilisant accidentellement de mauvais commutateurs.
Jpsy
Vous utilisez un commandement / dans votre commande
Jamie Cook
@ jpsy, votre avis sur la suppression du lien serait très utile s'il était vrai . Essayez de toucher zzzz; dissocier zzzz. (dissocier les appels, dissocier de la même manière que rm, mais sans options fantaisistes et sans récursivité).
ctrl-alt-delor
Pourquoi utiliser de -n? (peut être le problème). De plus, si votre support prend en charge, -tutilisez-le pour ces cas -Tou destination/pour d'autres cas.
ctrl-alt-delor

Réponses:

150

Utiliser -favec lnva écraser tout lien qui était déjà là, donc tant que vous avez les permissions appropriées, cela devrait fonctionner ... Cela a toujours fonctionné pour moi. Quel système d'exploitation utilisez-vous?

Sirch
la source
J'ai mis à jour ma question avec plus d'informations sur mon problème.
Jérôme Verstrynge
Je suis sous Linux.
Jérôme Verstrynge
2
Si vous changez les lnparamètres, comme je suis enclin à le faire, le -fcommutateur détruira-t-il vos fichiers existants (cibles de liens)? Dans les deux cas, nous avons également le -iparamètre (qui demandera à l'utilisateur de remplacer) si vous souhaitez un peu de sécurité.
Palswim
2
@palswim Cet article SO signifie qu'il est sûr car il -fsuffit d'appeler unlink()et de tomber link()sous le capot: stackoverflow.com/a/1466570/157385 . J'aimerais bien que je me souvienne du bon ordre!
Mike Branski
4
Ne marche pas. Besoins -n. Voir la réponse acceptée.
Shawn Welch
119

Ok, j'ai trouvé où est mon erreur: il ne faut pas mettre le premier /dans le chemin.

En d'autres termes, les commandes dans mes questions devraient être:

Creation -> ln -s {path/to/file-name} {link-name}
Update -> ln -sfn {path/to/file-name} {link-name}

au lieu de

Creation -> ln -s {/path/to/file-name} {link-name}
Update -> ln -sfn {/path/to/file-name} {link-name}

compte tenu de mon cas.

Jérôme Verstrynge
la source
22
Pour quelques informations supplémentaires sur la raison, les différences sont l’un est un relativechemin (sans le /) et l’autre est un absolutechemin (avec le /). Si vous administrez un système Linux, il est CRITIQUE de comprendre les différences. Par exemple, la différence entre rm -rf ./*et rm -rf /.*décide si vous conservez votre travail ou non :)
Safado
5
Cela ne répond pas à la question "comment mettre à jour / écraser un lien sym"
Sirch
La ligne ln -sfn {chemin / vers / nom-fichier} {nom-lien} le fait.
Jérôme Verstrynge
6
-n (--no-dereference) lui permet de traiter {nom du lien} comme un fichier normal plutôt que de suivre le lien. Étant donné que vous devez utiliser ce lien sans le suivre, vous devez utiliser cette option.
Feldoh
1
Cette réponse doit être mise en évidence avec le -nparamètre permettant de remplacer le lien de symbole.
Nick Tsai
12

Premier numéro:

En vous citant:

Les créations et les suppressions fonctionnent bien. Mais les mises à jour ne fonctionnent pas. Après avoir exécuté cette commande, le lien symbolique devient invalide.

Le problème avec la structure de répertoire donnée:

~ / scripts / test / ~ / scripts / test / remote_loc / ~ / scripts / test / remote_loc / site1 / ~ / scripts / test / remote_loc / site1 / stuff1.txt ~ / scripts / test / remote_loc / site2 / ~ / scripts /test/remote_loc/site2/stuff2.txt ~ / scripts / test / remote_loc / site2 / ~ / scripts / test / remote_loc / site3 / stuff3.txt

et en utilisant la commande:

ln -s /remote_loc/site1 test_link

Est-ce que cela crée un lien symbolique dans votre répertoire $ PWD, ou présent, qui pointe vers un fichier non existant de la racine /, ou racine, dans / remote_loc / site1

Si votre PWD est dans ~ / scripts /, alors vous devriez avoir utilisé ceci:

ln -s remote_loc/site1 test_link

sinon vous auriez pu utiliser le chemin absolu complet comme:

ln -s /home/yourusername/remote_loc/site1 test_link

Deuxième numéro:

En vous citant:

J'ai lu ici et là qu'il n'est pas possible de mettre à jour / remplacer un lien symbolique. Il y a donc des informations contradictoires sur le net. Qui a raison? Si un lien symbolique peut être mis à jour / remplacé, comment puis-je y parvenir?

Pour répondre à votre question "Qui a raison", je ne sais pas ce que vous avez lu exactement ni comment cela a été compris. Mais, les éléments suivants devraient aider à éclaircir:

  1. Que peut-on mettre à jour, et
  2. Que ne peut pas être mis à jour sans utiliser les commutateurs appropriés.


Mise à jour des liens symboliques avec des cibles qui ne sont pas des répertoires.

ln -sf:
le -f ou --force supprime les fichiers de destination existants. Ceci est utilisé pour mettre à jour la cible ou la destination d'un lien.

Exemple:

 ln -sf /tmp/test /tmp/test.link; ls -go /tmp |grep test
 -rw-r--r-- 1    0 Jun  8 17:19 test
 lrwxrwxrwx 1    9 Jun  8 17:27 test.link -> /tmp/test

Mais, comme vous pouvez le voir, cela donnera le chemin absolu si les chemins absolus sont dans lnles arguments de. Donner un chemin complet est nécessaire lorsque le répertoire de travail actuel est différent du répertoire parent du lien.


Chemins relatifs:

ln -sfr:
le -r ou --relative crée des liens symboliques relatifs à l'emplacement du lien.

Exemple:

ln -sfr /tmp/test  /tmp/test.link  ; ls -go /tmp| grep test
-rw-r--r-- 1    0 Jun  8 17:19 test
lrwxrwxrwx 1    4 Jun  8 17:27 test.link -> test

Cependant, la mise à jour d'un lien vers un répertoire ne fonctionnera pas si la cible est un répertoire.

Exemple:

ln -sf /tmp/testdir  /tmp/testdir.link  ; ls -go /tmp  |grep testdir
drwxr-xr-x 2 4096 Jun  8 17:48 testdir
lrwxrwxrwx 1    7 Jun  8 17:47 testdir.link -> testdir

Comme vous pouvez le constater, malgré l’utilisation des noms de chemins absolus indiqués dans lnl’argument ci-dessus sans l’option -r, le lien symbolique est toujours relatif au lien.


Mettre à jour les liens vers les répertoires:

ln -sfrn:
le -n ou --no-dereference considère LINK_NAME comme un fichier normal s'il s'agit d'un lien symbolique vers un répertoire.

Exemple:

ln -sfn /tmp/testdir /tmp/testdir.link; ls -go /tmp| grep testdir
drwxr-xr-x 2 4096 Jun  8 17:48 testdir
lrwxrwxrwx 1   12 Jun  8 17:48 testdir.link -> /tmp/testdir

Par opposition à:

ln -sfnr /tmp/testdir /tmp/testdir.link; ls -go /tmp| grep testdir
drwxr-xr-x 2 4096 Jun  8 17:48 testdir
lrwxrwxrwx 1    7 Jun  8 17:48 testdir.link -> testdir
Keith Reynolds
la source
6
$ touch test1 test2
$ ln -sf test2 test1
$ ls -l test[12]
lrwxrwxrwx 1 user01 user01 5 2012-05-17 14:41 test1 -> test2
-rw-r--r-- 1 user01 user01 0 2012-05-17 14:41 test2
jirib
la source
Lorsque j'effectue des tests avec 1 niveau de répertoire, cela fonctionne, mais j'essaie d'utiliser des répertoires à plusieurs niveaux et cela ne fonctionne pas. J'ai mis à jour ma question.
Jérôme Verstrynge