Por que mudar o diretório atual para o diretório pai de um symlink relativo antes de criá-lo

1

Do manual de coreutils, para ln

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.

A string armazenada em um symlink relativo é determinada completamente pelo nome do caminho de origem e pelo nome do caminho de destino, ambos especificados como argumentos da linha de comando para ln .

Não vejo como o diretório atual está envolvido. assim Eu não entendo muito bem o motivo pelo qual muitos usuários preferem alterar o diretório atual para o diretório pai de um symlink relativo a ser criado antes de criá-lo. Você poderia reformular ou dar alguns exemplos? Obrigado.

    
por Tim 03.07.2016 / 23:22

4 respostas

9

Há duas coisas para lembrar:

  1. ln -s (sem -r ) armazena o nome de destino literalmente ao passá-lo para ele
  2. se você passar um destino relativo, ele resolve relativamente ao nome do link , não ao seu diretório de trabalho atual

Exemplo:

Eu estou em /home/user/d0 e quero um link para /home/user/file , então eu faço:

ln -s ../file .

../file é um caminho válido de d0 .

Agora, se houver um subdiretório d1 ( /home/user/d0/d1 ) e eu quiser colocar um link para ../file ( /home/user/file ) lá sem alterar dirs, preciso fazer:

ln -s ../../file d1/ 

porque o caminho relativo precisa ser relativo ao nome do link , não ao meu diretório de trabalho atual. ../../file (provavelmente) resolve nada em relação a d0 (a menos que haja um arquivo chamado /home/file ), portanto, não receberei autocompletion para ele, o que pode tornar a operação mais propensa a erros.

Por isso, mudo para d1 primeiro:

cd d1
ln -s ../../file . 

e agora ../../file faz sentido em relação ao diretório atual e ao nome do link; o preenchimento automático entra em ação, e eu recebo minha garantia de que tenho o nome certo.

O GNU ln possui um --relative|-r flag, o que torna isso mais fácil, evitando que você tenha que compor esses caminhos relativos manualmente. Com ele, você pode usar um caminho relativo ao diretório atual ou a um caminho absoluto e relativá-lo em relação ao nome do link (como ele precisa ser).

    
por 03.07.2016 / 23:44
8

Se você fez

mkdir /tmp/foo
ln -s ../../etc/passwd /tmp/foo

Em seguida, acesse /tmp/foo/passwd para converter em /tmp/foo/../../etc/passwd - ou seja, /etc/passwd

Se você fez

mkdir /var/tmp/foo
ln -s ../../etc/passwd /var/tmp/foo

Em seguida, o acesso a /var/tmp/foo/passwd seria convertido em /var/tmp/foo/../../etc/passwd - ou seja, /var/etc/passwd

Assim, você pode ver que o "caminho relativo do symlink" é resolvido de forma diferente, dependendo de onde o link é salvo. O diretório atual em que você executa o comando ln não está envolvido de forma alguma.

Para evitar essa confusão, alguns usuários mudarão seu diretório atual antes de criar o symlink

mkdir /tmp/foo
cd /tmp/foo
ln -s ../../etc/passwd
    
por 03.07.2016 / 23:44
4

Você está absolutamente correto. O que vai no symlink é exatamente o que está especificado no comando. Mas o manual tenta dizer que o link simbólico será interpretado em relação à localização do link, então o usuário deve tomar cuidado para fazer o link corretamente.

Veja um exemplo:

/tmp/test$ mkdir bar
/tmp/test$ ls -l foo/aaa 
-rw-r--r-- 1 itvirta itvirta 0 Jul  4 00:37 foo/aaa
/tmp/test$ ln -si foo/aaa bar/

O arquivo está lá, exatamente onde pensamos que é, então podemos supor que o link funciona agora. Exceto que isso não acontece, já que o link é interpretado em relação à sua localização, não em relação ao local onde eu estava ao criá-lo.

/tmp/test$ cat bar/aaa 
cat: bar/aaa: No such file or directory

Se eu for para o diretório de destino antes de criar o link, tenho certeza de não ficar confuso:

/tmp/test$ cd bar
/tmp/test/bar$ ls -l ../foo/aaa 
-rw-r--r-- 1 itvirta itvirta 0 Jul  4 00:37 ../foo/aaa
/tmp/test/bar$ ln -si ../foo/aaa  .

No entanto, para aumentar a confusão, ao criar um link físico, a maneira de apontar para o arquivo de destino é exatamente a maneira óbvia que não funcionou ao criar um link simbólico:

/tmp/test$ ln foo/aaa bar/ 

Existe um lembrete porque os links simbólicos apontam pelo nome, não pela identidade do arquivo (inode) como praticamente todas as outras ações. Mover-se para o diretório de destino primeiro alinha os dois casos e reduz a chance de falhas humanas.

    
por 03.07.2016 / 23:54
1

Quando você digita ln -sT abc/fgh mno/xyz , ele armazena abc/fgh em um novo arquivo mno / xyz e define o bit do link. Quando você procurar em mno/xyz , você realmente procurará em mno/abc/fgh . Isso não importa (como você diz) em qual diretório você está quando cria ou usa o link.

No entanto:

Eles alteram os diretórios para o local em que o link simbólico relativo será criado, de modo que seu ponto de vista ao criá-lo seja o mesmo de quando ele é usado. Isso reduz a confusão. Além disso, ao usar a conclusão da tabulação, fica mais fácil, pois a conclusão da tabulação não funcionará de outra forma.

    
por 03.07.2016 / 23:46

Tags