J'ai créé un lien symbolique avec un chemin absolu vers le répertoire (Blink) et j'ai par exemple l'arborescence suivante:
$ ls -l /tmp/A
total 0
lrwxrwxrwx 1 root root 6 Apr 3 12:27 Blink -> /tmp/B
-rw-r--r-- 1 root root 0 Apr 3 12:27 foo
$ ls -l /tmp/B
total 0
-rw-r--r-- 1 root root 0 Apr 3 12:27 bar
puis je vais dans / tmp / A et je change de répertoire pour Blink:
$ cd /tmp/A
$ pwd
/tmp/A
$ cd Blink
$ pwd
/tmp/A/Blink
cd ..
me renvoie /tmp/A
mais si je tape par exemple ls ../foo
je vais avoir une erreur:
ls: ../foo: No such file or directory
La commande cd intégrée résout le chemin si nécessaire, mais les ls externes considèrent le .. comme un niveau supérieur de / tmp / B et ne peuvent donc pas trouver foo.
Quel est le problème ici? Puis-je obtenir le fichier foo de / tmp / A / Blink par un chemin relatif comme ../foo?
Réponses:
Je ne pense pas que vous puissiez faire ça. De nos jours, les shells gardent une trace de comment ils sont arrivés là où ils se trouvent, ils gardent la trace du répertoire de travail actuel par nom, plutôt que de simplement s'appuyer sur le système de fichiers et le système d'exploitation pour le garder. Cela signifie que la fonction intégrée
cd
peut "sauvegarder" le lien symbolique, plutôt que de suivre directement les chaînes "..".Mais lorsque vous exécutez
ls ../foo
, vous ne savezls
pas que le shell a atteint un répertoire en suivant des liens symboliques.ls
fera unstat()
sur "../foo". La partie ".." provient du répertoire courant, qui n'a qu'une seule entrée ".." pour son parent. L'ensemble du lien symbolique ne change pas la façon dont les répertoires ont un seul "." et une seule entrée "..". Les liens symboliques permettent au noyau d'insérer une couche supplémentaire d'indirection dans les chemins de fichiers. Lorsque vous transmettez "../n'importe quoi" àopen()
oustat()
, le noyau utilise simplement le répertoire de travail actuel du processus effectuant l'appel pour déterminer quel répertoire unique est nommé par "..".la source
Le shell stocke le répertoire de travail actuel dans
$PWD
. C'est ce qui est utilisé pour les commandes internes du shellcd
etpwd
, et il traite les liens symboliques comme des répertoires normaux, comme vous l'avez vu. Parfois, cela est utile, parfois non.Vous pouvez trouver le vrai répertoire en utilisant
pwd
(tapezhelp pwd
pour plus de détails):De même,
cd
a une option-P
(encore une fois,help cd
est votre ami):Enfin, vous pouvez désactiver complètement la "fonctionnalité":
la source
set -P
et le comportement de ls commencent à avoir un sens. :)Bruce et ams ont donné de belles réponses expliquant le comportement derrière. Mais pour faire ce que
ls ../foo
vous demandiez, vous pouvez aller avec quelque chose commela source
Vous ne pouvez pas le faire, parce que
/tmp/A/Blink
est en réalité/tmp/B
. Alorsls ../A/foo
ça marche.Vous pouvez plutôt trouver utile de pouvoir cd au vrai
/tmp/B
répertoire, plutôt que le crénelage/tmp/A/Blink
. Pour ce faire, vous pouvez utiliser la fonction suivante à la place decd
(que vous pouvez mettre dans votre .bashrc)lcd
, bien sûr, fonctionne pour les deux répertoires normaux et liés symboliquement.Remarque:
readlink -f
agit sur la cible finale du lien (lorsque les liens sont chaînés).la source
cd -P
semble plus simple.