Eu criei o link simbólico com o caminho absoluto para o diretório (Blink) e, por exemplo, tenho a seguinte árvore:
$ 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
então eu vou para / tmp / A e mudo o diretório para Blink:
$ cd /tmp/A
$ pwd
/tmp/A
$ cd Blink
$ pwd
/tmp/A/Blink
cd ..
retorna para mim, /tmp/A
mas se eu digitar, por exemplo ls ../foo
, recebo erro:
ls: ../foo: No such file or directory
O comando cd interno resolve o caminho conforme necessário, mas os ls externos consideram o .. como nível superior de / tmp / B e, portanto, não podem ser encontrados.
Qual é o problema aqui? Posso obter o arquivo foo de / tmp / A / Blink pelo caminho relativo como ../foo?
Respostas:
Eu não acho que você pode fazer isso. Atualmente, os shells controlam como chegaram onde estão, controlam o diretório de trabalho atual por nome, em vez de depender apenas do sistema de arquivos e do sistema operacional para mantê-lo. Isso significa que o built-in
cd
pode "fazer backup" do link simbólico, em vez de apenas seguir as cadeias ".." diretamente.Mas quando você executa
ls ../foo
,ls
não está ciente de que o shell chegou a um diretório seguindo os links simbólicos.ls
fará umstat()
"../foo". A parte ".." vem do diretório atual, que possui apenas uma única entrada ".." para seu pai. A coisa toda do link simbólico não muda a maneira como os diretórios têm um único "." e uma única entrada "..". Links simbólicos permitem que o kernel insira uma camada extra de indireção nos caminhos dos arquivos. Quando você passa "../whatever" paraopen()
oustat()
, o kernel apenas usa o diretório de trabalho atual do processo fazendo a chamada para descobrir qual diretório único é nomeado por "..".fonte
O shell armazena o diretório de trabalho atual em
$PWD
. Isso é o que é usado para as builtins shellcd
epwd
, e trata links simbólicos como diretórios normais, como você viu. Às vezes isso é útil, às vezes não.Você pode encontrar o diretório real usando
pwd
(digitehelp pwd
para obter mais detalhes):Da mesma forma,
cd
tem uma opção-P
(novamente,help cd
é seu amigo):Por fim, você pode desativar o "recurso" completamente:
fonte
set -P
e o comportamento começam a fazer sentido. :)Bruce e ams deram lindas respostas explicando o comportamento por trás. Mas para realmente fazer o que
ls ../foo
você estava perguntando, você poderia usar algo comofonte
Você não pode fazer isso, porque
/tmp/A/Blink
é realmente/tmp/B
. Então,ls ../A/foo
funciona.Em vez disso, você pode achar útil poder fazer o cd no diretório real
/tmp/B
, em vez do alias/tmp/A/Blink
. Para fazer isso, você pode usar a seguinte função em vez decd
(que você pode colocar no seu .bashrc)lcd
, é claro, funciona para os diretórios normais e vinculados simbólicos.Nota:
readlink -f
atua no destino final do link (quando os links são encadeados).fonte
cd -P
parece mais simples.