Por que meu link simbólico não funciona?

24

Estou tentando entender melhor os links simbólicos ... e não tendo muita sorte. Esta é minha saída real do shell com o nome de usuário / host alterado:

username@host:~$ mkdir actual
username@host:~$ mkdir proper
username@host:~$ touch actual/file-1.txt
username@host:~$ echo "file 1" > actual/file-1.txt
username@host:~$ touch actual/file-2.txt
username@host:~$ echo "file 2" > actual/file-2.txt
username@host:~$ ln -s actual/file-1.txt actual/file-2.txt proper
username@host:~$ # Now, try to use the files through their links
username@host:~$ cat proper/file-1.txt
cat: proper/file-1.txt: No such file or directory
username@host:~$ cat proper/file-2.txt
cat: proper/file-2.txt: No such file or directory
username@host:~$ # Check that actual files do in fact exist
username@host:~$ cat actual/file-1.txt
file 1
username@host:~$ cat actual/file-2.txt
file 2
username@host:~$ # Remove the links and go home :(
username@host:~$ rm proper/file-1.txt
username@host:~$ rm proper/file-2.txt

Eu pensei que um link simbólico deveria operar de forma transparente, no sentido de que você poderia operar no arquivo para o qual ele aponta como se estivesse acessando o arquivo diretamente (exceto, é claro, no caso de rmonde, é claro, o link é simplesmente removido )

orokusaki
fonte
Como seu disco é formatado? Qual sistema de arquivos você está usando? (FAT não suporta links simbólicos, mas se você tentar fazer em um sistema de arquivos FAT, deve dar um erro.)
Nicole Hamilton
@NicoleHamilton - É ext4 (de acordo com df -T) - o resultado acima é estranho para você também?
Orokusaki # 28/12
@orokusaki Não é estranho. Veja minha resposta abaixo. Apenas um aviso, não há necessidade de tocar em arquivos para atendê-los. Eles não precisam existir mesmo. Só para poupar algumas digitações!
Nerdwaller 28/11/2012

Respostas:

50

Os links simbólicos tendem a gostar de caminhos completos ou relativos ao link; caso contrário, eles podem estar procurando file-1.txtlocalmente (por incrível que pareça).

Navegue propere execute ls -le você pode ver que o link simbólico está procurando actual/file-1.txt, quando deveria ../actual/file-1.txt.

Então você tem duas opções:

  1. Dê o caminho completo

    ln -s ~/actual/file-1.txt ~/actual/file-2.txt ~/proper
  2. Navegue até a pasta em que você deseja que o link esteja e vincule a partir daí

    cd proper
    ln -s ../actual/file-1.txt ../actual/file-2.txt ./

Editar : Uma dica para salvar a digitação.

Você poderia fazer ln -s ~/actual/file-{1,2}.txt ~/proper

Os itens nos chavetas são substituídos e colocados um após o outro, criando o comando

ln -s ~/actual/file-1.txt ~/actual/file-2.txt ~/proper

que vincula os dois arquivos ao diretório de destino. Economiza digitação importante à medida que avança no shell.

nerdwaller
fonte
2
Obrigado - eu estava prestes a puxar meu cabelo antes de ler sua resposta.
Orokusaki # 28/12
1
Às vezes é confuso! O Linux tende a ser muito literal, por isso, se você disser fazer algo - será. Tenha cuidado com a ligação simbólica de pastas dessa maneira, eu substitui uma ou duas antes (basta especificar o nome sem uma barra). Além disso, não rm -rf *use uma pasta com link simbólico - você pode limpar a pasta à qual ele vincula. Apenas faça rm symlinkname. Apenas algumas coisas que eu cometi erros: D
nerdwaller 28/11/12
3

O problema é o uso de caminhos relativos. Se você especificar a criação do seu link com o caminho explícito completo, ele funcionará.

$ ln -s ~ / atual / arquivo1.txt ~ / atual / arquivo2.txt ~ / apropriado /

$ cat apropriado / file1.txt

arquivo 1

$

Seu exemplo cria links properpara procurar um subdiretório chamado real no diretório atual, em vez do pai ou pai de ambos.

Don Simon
fonte
1

Links simbólicos podem ser complicados. Em essência, um link simbólico é um arquivo que contém um nome de arquivo / caminho para outro arquivo (e é sinalizado para tratamento especial). Se o nome do caminho no arquivo de link começar com ' /', ele será tratado como um nome de caminho absoluto e as coisas serão bem diretas. Se não começar com uma barra, será tratado como um nome de caminho relativo - relativo ao diretório em que o link está localizado. (Isso é verdade independentemente de o nome conter ou não barras.) Então, você criou proper/file–1.txtcomo um link para “ actual/file–1.txt” e, quando tentou acessá-lo, o sistema tentou acessar proper/actual/file–1.txt. Você deveria ter dito

ln s  ../actual/file1.txt  ../actual/file2.txt  proper

A propósito, você não precisava dos touchcomandos.  echo "file 1" > actual/file–1.txté suficiente para criar actual/file–1.txt.

Scott
fonte
0

Um problema relacionado, e pode ser óbvio para muitos, mas me surpreendeu por alguns minutos: se você estiver criando um link simbólico dentro de um diretório que é linkado por si mesmo ou se houver um link simbólico no caminho do diretório de trabalho atual, você pode encontrar problemas com links simbólicos que não estão funcionando.

Use cd ..e ls -lrepetidamente, para verificar se os próprios diretórios-pai estão vinculados.

Se você precisar criar um link simbólico, cdpara o diretório de destino original e criar novos links simbólicos, para que os caminhos relativos sejam precisos.

Ou, dito de outra maneira: o caminho relativo é da Origem ao Destino. Se o Origin for posteriormente vinculado, tudo bem. Mas você pode ter problemas para configurar um novo nome de link de origem em um diretório que, de alguma forma, é de alguma forma vinculado.

Chrisky
fonte
1
Em vez de " cd ..e ls -lrepetidamente", você pode usar namei -mox $PWD. Outra forma útil para descobrir se existem links simbólicos ao longo do caminho é a utilização pwd -P, que lhe dá um caminho para o diretório atual que não contém quaisquer links simbólicos (por isso, se pwde pwd -Pdar saída diferente, você sabe que há um algum lugar link simbólico ao longo do caminho )
Ansa211 23/11
0

Quando você tenta criar um link para um arquivo que não existe (ou você deu o caminho incorretamente), ln -s não gera um erro. Ele cria um link, mas quando você tenta 'cat' nesse link, ele diz que nenhum arquivo foi encontrado. Mesmo quando você pode vê-lo usando ls. Nesses casos, verifique sempre o caminho do arquivo.

ubuntu@ip-172-31-80-155:~/lab5$ ln -s etc/ufw/ufw.conf link1
ubuntu@ip-172-31-80-155:~/lab5$ ls -al
total 5360
drwxrwxr-x 2 ubuntu ubuntu    4096 Mar  9 18:56 .
drwxr-xr-x 7 ubuntu ubuntu    4096 Mar  9 18:42 ..
-rwxr--r-- 1 ubuntu ubuntu 5478400 Mar  9 18:32 backup.tar
lrwxrwxrwx 1 ubuntu ubuntu      16 Mar  9 18:56 link1 -> etc/ufw/ufw.conf
ubuntu@ip-172-31-80-155:~/lab5$ cat link1
cat: link1: No such file or directory

Porque o arquivo etc / ufw / ufw.conf não existe. O caminho correto é /etc/ufw/ufw.conf

ubuntu@ip-172-31-80-155:~/lab5$ ln -s /etc/ufw/ufw.conf link2
ubuntu@ip-172-31-80-155:~/lab5$ ls -l
total 5352
-rwxr--r-- 1 ubuntu ubuntu 5478400 Mar  9 18:32 backup.tar
lrwxrwxrwx 1 ubuntu ubuntu      16 Mar  9 18:56 link1 -> etc/ufw/ufw.conf
lrwxrwxrwx 1 ubuntu ubuntu      17 Mar  9 19:00 link2 -> /etc/ufw/ufw.conf
ubuntu@ip-172-31-80-155:~/lab5$ cat link2
# /etc/ufw/ufw.conf
#

# Set to yes to start on boot. If setting this remotely, be sure to add a rule
# to allow your remote connection before starting ufw. Eg: 'ufw allow 22/tcp'
ENABLED=no

# Please use the 'ufw' command to set the loglevel. Eg: 'ufw logging medium'.
# See 'man ufw' for details.
LOGLEVEL=low
sindhura
fonte
Já existe uma resposta melhor, e a primeira parte, que ln -s"às vezes" não verifica a existência do alvo, está errada.
RalfFriedl 9/03