Encuentra solo el destino del enlace simbólico


50

Para usar en un script de shell, estoy buscando una forma de línea de comandos para obtener el destino de un enlace simbólico. Lo más cerca que he llegado hasta ahora es stat -N src, qué salidas src -> dst. Por supuesto, podría analizar la salida y obtener dst, pero me pregunto si hay alguna forma directa de obtener el destino.

Respuestas:


61

Otra opción sería utilizar el comando diseñado específicamente readlinksi está disponible.

P.ej

$ readlink -f `command -v php`
/usr/bin/php7.1

21
Úselo readlink -fsi desea conocer el último objetivo del enlace simbólico y no solo el siguiente .
scai

¡Buen punto! Olvidé eso.
nikitautiu

11
Tenga en cuenta que -fes una extensión no portátil de GNU readlink.
bahamat

2
¿Cuándo readlink no estará disponible? Gracias.
tommy.carstensen

2
@ tommy.carstensen readlink (1) se agregó a GNU coreutils en 2003, por lo que en estos días es probable que pueda depender de él en prácticamente todos los sistemas que usan coreutils. (Cf. git.savannah.gnu.org/cgit/coreutils.git/commit/src/… )
Josip Rodin

16

En Mac OS X y FreeBSD / NetBSD / etc. sus:

stat -f %Y <filename>

Más genéricamente supongo que la solución es (stat --printf =% N usa comillas extrañas):

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

Ejemplo:

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

Otro método es:

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

La última línea está destrozada porque no tiene nueva línea, pero está bien si necesita el resultado en una variable, como así

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

Se -maxdepthnecesita para evitar finddescender a directorios si bresulta ser un directorio.


Lo hojeé por completo, stat --printf='%N\n'es exactamente lo que quiero, las citas extrañas no me molestan, sus mismas citas rm y ln
interactivo

Aparentemente, esto no es portátil porque en Linux, el stat (1) de GNU coreutils tiene diferentes parámetros e imprime link -> desten la salida. La solución find (1) debe verificarse si es con GNU findutils o de lo contrario ...
Josip Rodin

Por favor, no olvide citar sus expansiones variables, echo $fciertamente no produce lo que espera cuando el enlace simbólico apunta a /*(sí, es posible)
Camusensei

3

Esto se puede hacer usando GNU find: find src -prune -printf "%l\n".


1

Portablemente: sin suerte, excepto el uso de heurística para analizar la salida ls -l, o usar perl -le 'print readlink("some-file")'

algunos sistemas tienen un readlinkcomando, algunos con una -fopción para obtener la ruta absoluta.

Hay varias implementaciones de un statcomando como envoltorio para las llamadas stat/ lstatsystem. El GNU uno no es útil en ese sentido, pero el incorporado de zsh lo es más:

zmodload zsh/stat
stat +link the-link

Aún con zsh, puede obtener la ruta absoluta de un archivo (elimina todos los componentes de enlace simbólico) con el :Amodificador (se aplica a la expansión variable, la expansión del historial y el 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

1

En un sistema donde no tengo readlinko tengo statcomandos pero tengo Python 2.x, estoy usando un script corto:

#!/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

Tenga en cuenta que, a diferencia de readlink -festo, solo puede seguir un nivel de enlace simbólico.


1

Realpath portátil puro de Bash

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}"
}

0

realpathcomando del coreutilspaquete,

como se vincula en readlinkla página del manual de comandos.


por ejemplo:

realpath /bin/python

salidas

/usr/bin/python2.7

en mi maquina

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.