Encontre apenas o destino do link simbólico

50

Para uso em um shell-script, estou procurando uma maneira de linha de comando para obter o destino de um link simbólico. O mais próximo que eu cheguei até agora é o stat -N srcresultado src -> dst. É claro que eu poderia analisar a saída e obter dst, mas gostaria de saber se existe alguma maneira direta de obter o destino.

gerrit
fonte

Respostas:

61

Outra opção seria usar o comando projetado especificamente, readlinkse disponível.

Por exemplo

$ readlink -f `command -v php`
/usr/bin/php7.1
nikitautiu
fonte
21
Use readlink -fse você deseja conhecer o último destino do link simbólico e não apenas o próximo .
ScaI
Bom ponto! Esqueci isso.
Nikitautiu 10/09/12
11
Observe que -fé uma extensão não portátil para o GNU readlink.
bahamat 10/09/12
2
Quando o readlink não estaria disponível? Obrigado.
Tommy.carstensen
2
O @ tommy.carstensen readlink (1) foi adicionado ao GNU coreutils em 2003, portanto, hoje em dia você provavelmente pode confiar nele em praticamente todos os sistemas que usam coreutils. (Cf. git.savannah.gnu.org/cgit/coreutils.git/commit/src/… )
Josip Rodin
16

No Mac OS X e FreeBSD / NetBSD / etc. Está:

stat -f %Y <filename>

Mais genericamente, acho que a solução é (stat --printf =% N usa aspas estranhas):

ls -l b | sed -e 's/.* -> //'

Exemplo:

# ln -s a b
# stat -f %Y b
a

Outro método é:

# find b -maxdepth 0 -printf %l
a#

A última linha é desconfigurada porque não possui nova linha, mas tudo bem se você precisar do resultado em uma variável, como

# f=$(find b -maxdepth 0 -printf %l)
# echo $f
a

O -maxdepthé necessário para evitar finda partir descendente em diretórios se bpassa a ser um diretório.

Coroos
fonte
I totalmente desnatado mais, stat --printf='%N\n'é exatamente o que eu quero, citações estranhas não me incomoda, suas as mesmas citações Rm e uso --interactive ln
ThorSummoner
Aparentemente, isso não é portátil, porque no Linux, o stat (1) do GNU coreutils tem parâmetros diferentes e é impresso link -> destna saída. O (1) solução achado deve ser verificado se é com findutils GNU ou de outra forma ...
Josip Rodin
Por favor, não se esqueça de citar suas expansões variáveis, echo $fcertamente não produz o que você espera quando o link simbólico aponta para /*(sim, é possível)
Camusensei
3

Isso pode ser feito usando o GNU find: find src -prune -printf "%l\n".

gerrit
fonte
1

Portably: sem sorte, exceto usando heurísticas para analisar a saída ls -l ou usar perl -le 'print readlink("some-file")'

alguns sistemas têm um readlinkcomando, alguns com uma -fopção para obter o caminho absoluto.

Existem várias implementações de um statcomando como um wrapper para as chamadas stat/ lstatsystem. O GNU one não é útil nesse sentido, mas o built-in do zsh é mais:

zmodload zsh/stat
stat +link the-link

Ainda com o zsh, você pode obter o caminho absoluto de um arquivo (remove todos os componentes do link simbólico) com o :Amodificador (aplica-se à expansão variável, expansão de histórico e globbing:

~$ gstat -c %N b
`b' -> `a'
~$ var=b
~$ echo $var:A
/home/me/a
~$ echo b(:A)
/home/me/a
~$ echo ?(@:A)
/home/me/a
Stéphane Chazelas
fonte
1

Em um sistema em que não tenho readlinkou não tenho statcomandos, mas tenho o Python 2.x, estou usando um script curto:

#!/usr/bin/env python

import os, sys

if __name__ == "__main__":
    src = sys.argv[1]
    target = os.readlink(src)
    if not os.path.isabs(target):
            target = os.path.abspath(os.path.join(os.path.dirname(src), target))
    print target

Observe que, diferentemente readlink -fdisso, pode seguir apenas um nível de link simbólico.

rakslice
fonte
1

Caminho real portátil do Bash puro

bash_realpath() {
  # print the resolved path
  # @params
  # 1: the path to resolve
  # @return
  # &1: the resolved link path

  local path="${1}"
  while [[ -L ${path} && "$(ls -l "${path}")" =~ -\>\ (.*) ]]
  do
    path="${BASH_REMATCH[1]}"
  done
  echo "${path}"
}
Léa Gris
fonte
0

realpathcomando do coreutilspacote,

conforme vinculado na readlinkpágina de manual do comando.


por exemplo:

realpath /bin/python

saídas

/usr/bin/python2.7

na minha máquina.


fonte