Outra opção seria usar o comando especificamente projetado readlink
, se disponível.
Por exemplo,
$ readlink -f 'command -v php'
/usr/bin/php7.1
Para uso em um script de shell, estou procurando uma forma de linha de comando para obter o destino de um link simbólico. O mais próximo que cheguei até agora é stat -N src
, que gera 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.
No Mac OS X e no FreeBSD / NetBSD / etc. é:
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 tem nova linha, mas isso é bom se você precisar do resultado em uma variável, assim
# f=$(find b -maxdepth 0 -printf %l)
# echo $f
a
O -maxdepth
é necessário para impedir que find
entre em diretórios se b
for um diretório.
Isso pode ser feito usando o GNU find
: find src -prune -printf "%l\n"
.
Portável: sem sorte, exceto usar heurística para analisar a saída ls -l ou usar perl -le 'print readlink("some-file")'
alguns sistemas têm um comando readlink
, alguns com uma opção -f
para obter o caminho absoluto.
Existem várias implementações de um comando stat
como um wrapper para as chamadas do sistema stat
/ lstat
. O GNU não é útil a esse respeito, mas o de zsh é mais:
zmodload zsh/stat
stat +link the-link
Ainda com o zsh, você pode obter o caminho absoluto de um arquivo (remove cada componente do symlink) com o modificador :A
(aplica-se à expansão de variáveis, expansão do 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
Em um sistema no qual eu não tenho nenhum comando readlink
ou stat
, mas eu 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 de readlink -f
, isso pode seguir apenas um nível de link simbólico.
realpath
do comando coreutils
package,
como vinculado na página de manual do comando readlink
.
por exemplo:
realpath /bin/python
saídas
/usr/bin/python2.7
na minha máquina.
Tags command-line symlink