O destino do link simbólico é relativo ao diretório pai do destino e, se sim, por quê?

14

Eu tenho a seguinte estrutura de arquivo:

build/
client/
  –> index.js

E quando tento criar um link simbólico chamado "cliente" dentro do diretório de compilação que se refere ao diretório de clientes no cwd, assim

// Fails
$ pwd
/home/user/
$ ln -s client build/client 
$ stat build/client/index.js
stat: build/client/index.js: stat: Too many levels of symbolic links

Eu recebo o erro ELOOP exibido acima. Quando eu mudo o caminho de destino para ser relativo ao caminho de destino, tudo fica bem:

// Works
$ pwd
/home/user/
$ ln -s ../client build/client 
$ stat build/client/index.js
stat: <outputs file stats>

Esse é o comportamento pretendido e explique por que ...

jibsales
fonte
isso provavelmente tem algo a ver com o efeito de que usar ../ use caminho absoluto para declarar o caminho em vez do caminho relativo. uma boa pratice é sempre usar caminho absoluto
kiwy
Concordo com as melhores práticas, pois sempre usei caminhos absolutos para o destino e o destino. No entanto, o estado homem páginas que caminhos relativos podem ser usados tanto para ...
jibsales

Respostas:

13

Para aquele que não funciona, se olharmos para o ls -lresultado, obtemos o seguinte:

[sparticvs@sparta test]$ ls -l build/
total 0
lrwxrwxrwx. 1 sparticvs sparticvs 6 Dec 17 16:08 client -> client

Agora, para entender o que está acontecendo aqui. Vamos dar uma olhada no comando que você chamou:

ln -s client build/client

De acordo com a página do manual, há duas correspondências possíveis para este formato

SYNOPSIS
       ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
       ln [OPTION]... TARGET... DIRECTORY     (3rd form)

Ele corresponderá no primeiro formulário (desde o primeiro). Agora, o "nome do destino" ou, clientno seu caso, pode ser (de acordo com o lnmanual completo ) seqüências arbitrárias. Eles não precisam resolver nada agora, mas podem resolver algo no futuro. O que você está criando com sua chamada é um "link simbólico dangling" e o sistema não impede que você os crie.

Agora sua segunda invocação ln -s ../client build/clienté chamada de "link simbólico relativo" (como você observou em sua própria postagem). Existe um segundo tipo e esse é um "link simbólico absoluto" que seria chamado por fazer ln -s /home/user/client build/client.

Isso não é um bug. De acordo com o manual, afirma:

Ao criar um link simbólico relativo em um local diferente do diretório atual, a resolução do link simbólico será diferente da resolução da mesma sequência do diretório atual. Portanto, muitos usuários preferem alterar primeiro os diretórios para o local em que o link simbólico relativo será criado, para que a conclusão da guia ou outra resolução de arquivo encontre o mesmo destino do que será colocado no link simbólico.

-- a partir de info coreutils 'ln invocation'

Dito isto, você DEVE usar o caminho relativo ou absoluto para o alvo.

sparticvs
fonte
5

Este é realmente o comportamento pretendido. Na ln(1)página do manual:

Links simbólicos podem conter texto arbitrário; se posteriormente resolvido, um link relativo será interpretado em relação ao seu diretório pai.

Quanto ao porquê disso, imagine se o link simbólico fosse interpretado em relação à sua origem e não ao seu destino. Ao resolvê-lo posteriormente, você precisaria saber qual era o seu CWD quando o criou, o que não faz sentido, e muito menos é impossível.

Além disso, dessa maneira, você obtém um método limpo e compacto para criar uma estrutura de diretório esquelética que pode ser solta em qualquer lugar na árvore de diretórios sem quebrar os links simbólicos.

Para dar um exemplo do que quero dizer, digamos que você esteja trabalhando em um projeto e tenha uma estrutura de diretórios inteira configurada para isso da seguinte maneira:

$ ls -1 /home/you/project
thingummies/
widgets/
wizardry/

Agora, suponha que você deseje criar um link simbólico para widgets/dentro wizardry/. Você tem duas opções:

$ ln -s /home/you/project/widgets /home/you/project/wizardry

ou

$ ln -s ../widgets /home/you/project/wizardry

Se você tentar se mover para /home/you/projectoutro lugar, um link simbólico criado com o primeiro formulário será interrompido porque está procurando /home/you/project/widgets. O segundo formulário manterá o link simbólico funcional, pois ele procura em ../widgets relação ao local em que está, independentemente de onde esse local possa estar na árvore de diretórios.

Joseph R.
fonte