Comportamento aparentemente inconsistente para “ln” e “ln -s”

1

Como todos sabemos, o comando ln cria um link, com o padrão sendo um hard link e a opção -s criando um symlink. A sintaxe geral é ln [-s] OLD NEW , em que OLD é o arquivo ao qual você está vinculando e NEW é o novo arquivo que você está criando. Links rígidos não podem ser criados para diretórios, pois um link físico pode ser criado entre pastas dentro de outras e & Suponho que os computadores ainda não tenham recursos para verificar isso sem uma lentidão SÉRIA.

Ao criar o link, o caminho de ambos os arquivos deve ser gravado e pode ser absoluto ou relativo. Você pode misturar parente & caminhos de arquivo absolutos, ou seja, têm um caminho relativo para o novo arquivo / pasta & um caminho absoluto para o antigo. Ao criar um link físico com um caminho relativo, os caminhos de ambos os arquivos são relativos à pasta atual, enquanto que, para um link simbólico, o caminho do arquivo / pasta vinculado é relativo à sua pasta pai, mas o caminho do arquivo antigo / pasta é relativo à pasta atual. Por que isso é "relativo" à minha pergunta.

Por exemplo, digamos que estamos na pasta HOME, /home/user , também conhecido como ~ , e crie duas pastas, new e new2 , com o arquivo file na pasta new . Se tentarmos ln -s new/file new2/file , o resultado será um link quebrado de ~/new2/file para o ~/new2/new/file atualmente inexistente. No entanto, se, em vez disso, executarmos ln -s ../new/file new2/file , obteremos o resultado esperado, que é um link de ~/new2/file a ~/new/file .

Então, minha pergunta:

Por que o caminho do arquivo para o arquivo / pasta OLD de um link simbólico em relação ao seu pai, enquanto os outros 3 caminhos (link rígido OLD, arquivos NOVOS, arquivo / pasta simbólica NEW) são relativos à pasta atual?

Tudo isso está no Fedora, mas tenho certeza que se aplica à maioria dos sistemas operacionais baseados em UNIX.

EDIT E Carter Young parece acertar na minha cabeça em relação à minha segunda pergunta (assim como a minha primeira pergunta, que estava errada de qualquer forma). Parece que para um link simbólico, o alvo não precisa existir ainda, então o sistema tem que fazer seu caminho relativo ao link em vez do diretório atual. No entanto, por que o shell não pode analisar esse caminho quando você está executando o comando, em vez de forçar o usuário a descobrir qual é o caminho & entrar ele mesmo? O shell parece analisar muito bem, então isso é um caso de problemas legados? Problemas de desempenho? O que?

    
por trysis 15.04.2014 / 23:04

3 respostas

6

Leia a sua página man: Questão 1 = 1º Formulário, isso porque no linux todos os itens são considerados arquivos, até diretórios. Como exemplo, use seu editor de texto para "abrir" / etc /, ou seja: nano -w / etc / nano irá educadamente dizer a você / etc / é um diretório Já que é tecnicamente legal criar links simbólicos sem fim. Antigamente, antes que a verificação dos limites fosse escrita, eu poderia ter um sistema FHS com 2 arquivos chamados / etc, um deles sendo um arquivo e um sendo um diretório, e o sistema sabia a diferença

(Veja a nota haha no guia do desenvolvedor do chromiumos :

There is a file system loop because inside ~/trunk you will find the chroot again. Don't think about this for too long. If you try to use du -s ${HOME}/chromiumos/chroot/home you might get a message about a corrupted file system. This is nothing to worry about, and just means that your computer doesn't understand this loop either. (If you can understand this loop, try something harder.

Eu te desafio, clique em algo mais difícil :) A fim de evitar o looping, o ln requer o caminho completo.

A pergunta 2 pode ser respondida lendo novamente a página de manual Veja a última frase:

DESCRIPTION

   In the 1st form, create a link to TARGET with the name LINK_NAME.  In
   the 2nd form, create a link to TARGET in the current directory.  In
   the 3rd and 4th forms, create links to each TARGET in DIRECTORY.
   Create hard links by default, symbolic links with --symbolic.  By
   default, each destination (name of new link) should not already
   exist.  When creating hard links, each TARGET must exist.  Symbolic
   links can hold arbitrary text; if later resolved, a relative link is
   interpreted in relation to its parent directory.

Re: Editar: "No entanto, por que o shell não pode analisar esse caminho quando você está executando o comando, em vez de forçar o usuário a descobrir qual é o caminho? & enter ela própria? "

Considere este exemplo: Aplicativo A instala versão da biblioteca 1.0.a. Você constrói os aplicativos X, Y, Z que dependem da Biblioteca A. O aplicativo A encontra um bug, atualiza-o e salva a biblioteca como 1.0.1.2.a. Como os Aplicativos X, Y e Z ainda usam a biblioteca 1.0, se eu substituir 1.0 diretamente w / 1.0.1.2, serei quebrado, mas se eu vincular simbolicamente a versão 1.0.1.2 à versão 1.0, nada quebrará,

ln -s /usr/lib64/libfoo-1.0.1.2.a /usr/lib64/libfoo-1.0.a

e os aplicativos X, Y e Z recebem a nova correção de bugs da biblioteca aplicada a eles também, porque o shell segue o link de 1.0 para 1.0.1.2, mas o chama de 1.0. Em casos como esse, você não deseja que o shell assuma o caminho, pois aumenta a chance de quebra do sistema. BTW em sistemas de 64 bits / usr / lib está vinculada a / usr / lib64, para remediar o exemplo que acabei de dar em larga escala, ou seja, aplicativos de 32 bits esperam que bibliotecas sejam instaladas em / usr / lib, e em 64 bits sistema não há bibliotecas de 32 bits, portanto / usr / lib está ligado a / usr / lib64 da seguinte forma:

ln -s /usr/lib64 /usr/lib
    
por 15.04.2014 / 23:47
2

Question 1: Why does the whole path need to be written out for both files/folders for a soft link, while for a hard link we can leave out the filename for the target file?

Você também não precisa especificar o caminho ou o nome do arquivo para o link virtual, a menos que o destino esteja no diretório atual. Por exemplo, se você tiver um arquivo ~/Downloads/target_file , poderá fazer:

ln '~/Downloads/target_file'

quando estiver em ~/ , o que criará um link físico para ~/Downloads/target_file em ~/ com o nome de arquivo target_file e você também pode fazer

ln -s '~/Downloads/target_file'

quando estiver em ~/ , o que criará um link suave para ~/Downloads/target_file em ~/ com o nome de arquivo target_file .

Question 2: Why is the file path for the OLD file/folder of a soft link relative to its parent, while the other 3 paths (hard link OLD, NEW files, soft link NEW file/folder) are relative to the files/folders themselves?

Todos os quatro caminhos podem ser relativos (à pasta atual) e absolutos; o único critério é o hard ou o link não deve estar na mesma pasta se você não estiver especificando o nome ou o caminho.

Você deve ler a página de manual do ln . Já tentei tudo isso no Ubuntu 14.04, mas nunca a menos confirmou com a página de manual, assim você não precisa se preocupar com o sistema operacional; não é específico do sistema operacional.

    
por 15.04.2014 / 23:39
2

Quando você cria um link físico, o caminho de origem é usado no momento da criação do link, portanto, ele deve ser um caminho relativo ao diretório de trabalho atual (ou um caminho absoluto). Quando você cria um link simbólico, o caminho de origem é tratado como uma string; ele será interpretado quando o link for usado, por isso é relativo ao diretório onde o link está.

Considerando o seu exemplo, onde o diretório atual é /home/user .

  • O comando ln -s new/file new2/file cria um link simbólico cujo texto é new/file e coloca esse link no local new2/file . Quando um programa acessa esse link, o destino é /home/user/new2/new/file , o que não existe.
  • O comando ln -s ../new/file new2/file cria um link simbólico cujo texto é ../new/file e coloca esse link no local new2/file . Quando um programa acessa esse link, o destino é /home/user/new2/../new/file , que é reduzido para /home/user/new/file .
  • O comando ln new/file new2/file cria uma entrada de diretório na localização new2/file , que aponta para o mesmo arquivo que /home/user/new/file (que deve existir).

Geralmente, é menos confuso mudar para o diretório de destino antes de criar links simbólicos.

cd new2
ln -s ../new/file .
    
por 16.04.2014 / 03:38