O destino do symlink é relativo ao diretório pai do destino e, em caso afirmativo, por quê?

12

Eu tenho a seguinte estrutura de arquivos:

build/
client/
  –> index.js

E quando eu tento criar um link simbólico chamado "cliente" dentro do diretório de compilação que se refere ao diretório do cliente 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 altero o caminho de destino para o caminho de destino, tudo é bom:

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

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

    
por jibsales 17.12.2013 / 22:34

2 respostas

12

Para o que não funciona, se olharmos para o resultado ls -l , obtemos o seguinte:

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

Agora, entenda o que está acontecendo aqui. Vamos ver o comando que você chamou:

ln -s client build/client

De acordo com a Man Page, existem 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 de destino" ou client no seu caso, pode ser (de acordo com o manual completo ln ) seqüências arbitrárias. Eles não precisam resolver nada agora, mas podem resolver algo no futuro. O que você está criando com sua invocação é um "link simbólico pendente" e o sistema não impede que você crie esses arquivos.

Agora, sua segunda invocação ln -s ../client build/client é o que é chamado de "link simbólico relativo" (como você observou em seu próprio post). Existe um segundo tipo e esse é um "symlink absoluto" que seria chamado fazendo ln -s /home/user/client build/client .

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

When creating a relative symlink in a different location than the current directory, the resolution of the symlink will be different than the resolution of the same string from the current directory. Therefore, many users prefer to first change directories to the location where the relative symlink will be created, so that tab-completion or other file resolution will find the same target as what will be placed in the symlink.

-- from info coreutils 'ln invocation'

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

    
por 17.12.2013 / 23:19
5

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

Symbolic links can hold arbitrary text; if later resolved, a relative link is interpreted in relation to its parent directory.

Quanto ao porquê, imagine se o symlink fosse interpretado em relação à sua origem, e não ao seu destino. Quando mais tarde resolvê-lo, você precisaria saber qual era o seu CWD quando o criou, o que é sem sentido, quanto mais impossível.

Além disso, desta forma você obtém um método puro e compacto para criar uma estrutura de diretórios esqueletos que você pode soltar 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 toda uma estrutura de diretórios configurada para isso da seguinte forma:

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

Agora, suponha que você queira criar um link simbólico para widgets/ dentro de 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 mover /home/you/project em qualquer outro lugar, um link simbólico criado com o primeiro formulário será quebrado porque está procurando por /home/you/project/widgets . O segundo formulário manterá o link simbólico funcional porque está procurando por ../widgets relativo ao local em que está, independentemente de onde esse local possa estar na árvore de diretórios.

    
por 17.12.2013 / 23:16

Tags