Faça um link simbólico para um nome de caminho relativo

64

Eu posso fazer isso:

$ pwd
/home/beau
$ ln -s /home/beau/foo/bar.txt /home/beau/bar.txt
$ readlink -f bar.txt
/home/beau/foo/bar.txt

Mas eu gostaria de poder fazer isso:

$ pwd
/home/beau
$ cd foo
$ ln -s bar.txt /home/beau/bar.txt
$ readlink -f /home/beau/bar.txt
/home/beau/foo/bar.txt

Isso é possível? De alguma forma, posso resolver o nome do caminho relativo e passá-lo para ln?

Humphrey Bogart
fonte
Mas qual é o problema que seria resolvido com o comportamento descrito?
forcefsck
Bem, digamos que você ofereça uma pasta compactada para download e gostaria de dar instruções de copiar e colar sobre como vincular alguns dos arquivos da pasta.
Humphrey Bogart
2
ln -s $(pwd)/bar.txt ~/ou inclua um script de instalação.
forcefsck
2
na verdade, o link armazena o nome que você usa na linha de comando. A resolução desse nome para um arquivo é feita em relação ao local do link. Você tem que usarln -s foo/bar.txt /home/beau/bar.txt
pqnet

Respostas:

62

Se você criar um link simbólico para um caminho relativo, ele será armazenado como um link simbólico relativo, não absoluto, como mostra o seu exemplo. Isso geralmente é uma coisa boa. Links simbólicos absolutos não funcionam quando o sistema de arquivos está montado em outro lugar.

O motivo pelo qual seu exemplo não funciona é que ele é relativo ao diretório pai do link simbólico e não onde lné executado.

Você pode fazer:

$ pwd
/home/beau
$ ln -s foo/bar.txt bar.txt
$ readlink -f /home/beau/bar.txt
/home/beau/foo/bar.txt

Ou para esse assunto:

$ cd foo
$ ln -s foo/bar.txt ../bar.txt

É importante perceber que o primeiro argumento depois ln -sé armazenado como o destino do link simbólico. Pode ser qualquer string arbitrária (com as únicas restrições de que não pode estar vazio e não pode conter o caractere NUL), mas no momento em que o link simbólico está sendo usado e resolvido, essa string é entendida como um caminho relativo para o diretório pai do link simbólico (quando não inicia /).

penguin359
fonte
2
Bem dito. Você respondeu isso enquanto eu estava digitando minha própria resposta. :)
Shadur 31/03
Eu só tinha uma pergunta um pouco diferente - e isso responde perfeitamente. Eu queria saber como fazer referência ao diretório inicial no link simbólico para que funcionasse quando eu o transferisse de um usuário para outro. Eu não tinha certeza se algo assim ~iria funcionar.
25417 Joe
"essa string é entendida como um caminho relativo para o diretório pai do link simbólico" - isso explica tudo!
Bojan Komazec 26/09
24

Se você usa coreutils mais recentes (estou usando coreutils-8.22-11), ele tem uma opção para fazer isso:

ln --help | grep relative

pode conter texto arbitrário; se resolvido posteriormente, um link relativo será -r, --relative criar links simbólicos em relação ao local do link

Por exemplo:

$ mkdir /tmp/test
$ touch /tmp/test/to
$ ln -rs /tmp/test/to /tmp/test/from
$ ls -l /tmp/test/from
    lrwxrwxrwx 1 ptr ptr 4 aug   25 17.02 /tmp/test/to -> from
ptr
fonte
Hum, para mim parece que não existe essa opção -r. Usando Mac embora.
Ivkremer
11
@ivkremer parece que esta opção está disponível desde coreutils> = 8,16 (fonte: superuser.com/a/837935/403979 )
DJCrashdummy
Usar a bandeira relativa parecia esclarecer os problemas de "muitos níveis de links simbólicos" que eu estava enfrentando.
Vix
12

Desculpe, não. Os links simbólicos são relativos ao local em que o link está, não ao local em que você estava quando criou o link. Existem várias boas razões para esse comportamento, a maioria das quais envolve a montagem de sistemas de arquivos remotos.

Shadur
fonte
7

Há um pequeno utilitário conveniente chamado symlinks(originalmente por Mark Lords, agora mantido por J. Brandt Buckley), presente em muitas distribuições Linux.

Para converter todos os links simbólicos absolutos em um diretório para serem relativos:

symlinks -c /path/to/directory

Infelizmente, não há opção para converter um único link, você deve movê-lo para seu próprio diretório primeiro.

mkdir ../tmp
mv link-to-relativize ../tmp
symlinks ../tmp
mv ../tmp/* .
rmdir ../tmp
Gilles 'SO- parar de ser mau'
fonte
obrigado. links simbólicos disponíveis no github . Mantido por J. Brandt Buckley. v1.4.3 .
Evgeny Vereshchagin
3

Você poderia tentar:

ln -s `pwd`/bar.txt /home/beau/bar.txt

Mas, faz um link simbólico com o nome do caminho absoluto. Sua pergunta textual faz menção ao nome do caminho relativo ...

Normalmente, um nome de caminho relativo é o que você deseja e o que ln -soferece. Eu acho que o que você quer é:

cd /home/beau
ln -s foo/bar.txt bar.txt
MattBianco
fonte
1

À medida que os shells mais comuns expandem os caminhos, para criar um link simbólico relativo, você deve citar o "caminho de origem".

Além disso, o -sparâmetro significa --symbolic. lncria links físicos por padrão.

$ ln -s '../../relative_path' path
$ ls -al path

lrwxrwxrwx 1 empjustine empjustine 19 Aug  6 01:38 path -> ../../relative/path
emp.justine
fonte
0

Se você tem certeza de que não há chance de os seus pontos de montagem mudarem, você pode conseguir o que está tentando fazer em um shell bash como este:

ln -s `pwd`/bar.txt ~/bar.txt

Isso pressupõe que você esteja no diretório de destino ao criar o link simbólico.

mreff555
fonte