Muitos níveis de links simbólicos

100

Eu criei esta estrutura de arquivo:

test/src
test/firefox

Quando executo este comando:

ln -s test/src test/firefox

Eu esperaria que um link simbólico test/firefox/srcfosse criado apontando para test/src, no entanto, recebo esse erro:

-bash: cd: src: Too many levels of symbolic links
  • O que estou fazendo errado?
  • Você não pode criar um link simbólico para uma pasta armazenada em um irmão dessa pasta?
  • Qual o sentido disso?
David Zorychta
fonte
Não sei se sigo o que você fez. Poste a saída ls -ld test test/*ou a sequência exata de comandos que você executou para criar esses arquivos.
Gilles
teste mkdir; teste mkdir / src; teste do mkdir / firefox; ln -s test / src test / firefox
David Zorychta
Com esses comandos, cd test/firefox/srcmostraria o erro cd: no such file or directory: test/firefox/src, porque test/firefox/srcé um link simbólico dangling. Você está executando cdem algum outro link simbólico chamado src?
Gilles
Tenho certeza de que você fez algo entre o ln -se o cdque não nos diz. Supondo que haja apenas um testsubdiretório no diretório atual, um cd src(ou o que você executou) deve gerar um erro. Você colocou alguma coisa test/firefox?
Dubu
5
E como o @Gilles deu uma dica, esse link não fará o que você pensa que faz. Links simbólicos com destinos relativos são sempre relativos ao diretório de link simbólico , não ao diretório de onde você criou o link. Portanto, estando em um diretório /some/path, a ln -s test/src test/firefoxcriará um link simbólico apontando de /some/path/test/firefox/srcpara /some/path/test/firefox/test/src, e não para /some/path/test/src.
Dubu

Respostas:

32

Na superfície, o que você sugeriu que tentou funcionou para mim.

Exemplo

$ mkdir -p test/src test/firefox

$ tree --noreport -fp
.
`-- [drwxrwxr-x]  ./test
    |-- [drwxrwxr-x]  ./test/firefox
    `-- [drwxrwxr-x]  ./test/src

Faça o link simbólico:

$ ln -s test/src test/firefox

$ tree --noreport -fp
.
`-- [drwxrwxr-x]  ./test
    |-- [drwxrwxr-x]  ./test/firefox
    |   `-- [lrwxrwxrwx]  ./test/firefox/src -> test/src
    `-- [drwxrwxr-x]  ./test/src

Executá-lo uma segunda vez normalmente produziria o seguinte:

$ ln -s test/src test/firefox
ln: failed to create symbolic link ‘test/firefox/src’: File exists

Então você provavelmente tem algo mais acontecendo aqui. Eu suspeitaria que você tenha uma referência circular onde um link está apontando de volta para si mesmo.

Você pode usar findpara investigar isso um pouco:

$ cd /suspected/directory
$ find -L ./ -mindepth 15
slm
fonte
2
find -L ./ -mindepth 15revelou o culpado
user7610
167

Como Dubu aponta em um comentário, o problema está nos seus caminhos relativos. Eu tive um problema semelhante ao desvincular minha configuração do nginx de /usr/local/etc/nginxpara /etc/nginx. Se você criar seu link simbólico assim:

cd /usr/local/etc
ln -s nginx/ /etc/nginx

De fato, você criará o link / etc / nginx -> / etc / nginx, porque o caminho de origem é relativo ao caminho do link. A solução é tão simples quanto usar caminhos absolutos:

ln -s /usr/local/etc/nginx /etc/nginx
Steen Schütt
fonte
57
Essa resposta foi mais clara que a outra. "Use caminhos absolutos."
Wulftone
1
Posso confirmar que isso funcionou para mim no Windows usando cygwin. Obrigado!
dimiguel 28/09/2015
Muitas vezes tenho problemas para obter os argumentos corretos. No OSX e GNU Linux, eles são revertidos, o que me confunde ainda mais.
Daniel W.
Ainda não acredito que isso funcione.
PNDA
5
Você pode usar links relativos , mas eles devem se basear no diretório em que o link simbólico está . Em outras palavras: o primeiro argumento deve ser o mesmo que você escreveriacd se quiser ir para o diretório de destino no diretório em que está o arquivo do link simbólico.
totymedli
9

Os links simbólicos são relativos ao diretório pai do link, não ao diretório atual do lnprocesso.

Quando você faz:

cd /top/dir
ln -s test/src test/firefox

(onde test/firefoxestá um diretório), você está criando um test/firefox/srclink simbólico cujo destino é test/src.

Isso test/srcé relativo ao test/firefoxdiretório, então é um link simbólico para /top/dir/test/firefox/test/src.

Se você quisesse que o link simbólico fosse um link /top/dir/test/src, seria necessário escrever:

ln -s ../src test/firefox/

Ou

ln -s /top/dir/test/src test/firefox/

embora geralmente seja uma má idéia criar links simbólicos para caminhos absolutos, pois eles são facilmente quebrados quando os diretórios são renomeados ou os sistemas de arquivos montados em outro lugar.

Com o GNU ln, você pode usar sua -ropção para permitir que ele faça o cálculo sozinho:

$ ln -rs test/src test/firefox/
$ ls -ld test/firefox/src
lrwxrwxrwx 1 chazelas chazelas 6 Nov 29 15:59 test/firefox/src -> ../src
Stéphane Chazelas
fonte
5

Use o caminho absoluto em vez do caminho relativo, para que funcione.

Por exemplo:

ln -s /home/user/test/src /home/user/test/firefox
JISHNU TU
fonte
0

A resposta é usar o caminho absoluto. Mas pode ser irritante digitar o caminho completo para algo que esteja no diretório atual. Você pode usar a substituição de comandos do pwd para evitar isso. Se o seu destino estiver no diretório atual:

ln -s "$(pwd)"/target abs/path/to/link 

Se o seu link estiver no diretório atual:

ln -s /abs/path/to/target "$(pwd)"
breadnbeer
fonte