¿Cómo obtener la ruta completa del archivo original de un enlace simbólico suave?


99

Quiero scpun archivo a un servidor. El archivo es un enlace simbólico, y en realidad lo que quiero hacer es copiar el archivo fuente. De todos modos, no quiero rastrear la ruta del archivo fuente manualmente, porque puede ser reemplazado. Si puedo obtener la ruta absoluta del archivo fuente, puedo sephacerlo con ella. ¿Cómo puedo obtener el camino?


2
La mayoría de las scpversiones siguen enlaces simbólicos por defecto, ¿no? Deberías revisar el tuyo y quizás ahorrarte algo de trabajo.
jw013

@ jw103 Gracias por hacérmelo saber. No lo sabia :)
Eonil

2
Nota: scp -robliga a seguir los enlaces simbólicos.
Eonil

Respuestas:


129

Prueba esta línea:

readlink -f `which command`

Si commandestá en su $PATHvariable, de lo contrario, debe especificar la ruta que conoce.


12
-fdevolverá una ruta a un objetivo final inexistente, siempre que existan los objetivos de enlace intermedio ... Use -epara evitar esto, es decir. -edevolverá nulo si el objetivo final no existe.
Peter.O

10
-ferrado con readlink: illegal option -- fen OSX. Eliminarlo funcionó bien.
Heath Borders el

2
@HeathBorders Para OSX, si tiene instalados homeutils coreutils, también puede usarlos greadlink.
Adam Gent

23

En Linux, readlinklee el contenido de un enlace simbólico y readlink -fsigue enlaces simbólicos a enlaces simbólicos a enlaces simbólicos, etc., hasta que encuentra algo que no es un enlace simbólico.

Sin embargo, esto no es necesario para scp: scp siempre sigue enlaces simbólicos (siempre copia el contenido del archivo, ignorando los metadatos, excepto que -pconserva los tiempos y modos del archivo cuando es posible).

Si se siente decepcionado por los metadatos que scp puede y no puede preservar, le sugiero que use rsync. Sin opción, rsync copia el contenido del archivo ignorando los metadatos. La opción de uso común -aconserva todos los metadatos de variedades de jardín (tiempos, enlaces simbólicos, permisos y propiedad), y hay opciones para preservar metadatos exóticos como ACL y enlaces duros.


readlink realiza solo un paso para leer el enlace. por ejemplo en ubuntu tenemos / bin / zsh, que está enlazado a / etc / Alternatives / zsh, pero este es el segundo enlace simbólico. Finalmente, no obtendremos la ruta real del archivo o directorio. Lo mismo es con el comando stat. Solo el enlace de lectura con la opción -f resuelve todo.
Znik

9

Yo uso de comandos ls, stat, readlink.

Toma el archivo /etc/localtimecomo ejemplo

[flying@lempstacker ~]$ ls /etc/localtime 
/etc/localtime
[flying@lempstacker ~]$ ls -l /etc/localtime
lrwxrwxrwx. 1 root root 35 Aug  2 22:41 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai

Operación

Usando stat

[flying@lempstacker ~]$ stat /etc/localtime
  File: ‘/etc/localtime’ -> ‘../usr/share/zoneinfo/Asia/Shanghai’
  Size: 35          Blocks: 0          IO Block: 4096   symbolic link
Device: fd01h/64769d    Inode: 272202388   Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-11-23 09:00:59.999887800 +0800
Modify: 2016-08-02 22:41:26.090389904 +0800
Change: 2016-08-02 22:41:26.090389904 +0800
 Birth: -
[flying@lempstacker ~]$ stat -c "%N" /etc/localtime
‘/etc/localtime’ -> ‘../usr/share/zoneinfo/Asia/Shanghai’

Usando readlink

[flying@lempstacker ~]$ readlink /etc/localtime
../usr/share/zoneinfo/Asia/Shanghai
[flying@lempstacker ~]$ readlink -f /etc/localtime
/usr/share/zoneinfo/Asia/Shanghai

Parece que ese comando readlink -fes mejor.

Explicación

-f, --canonicalize: canonicalize siguiendo cada enlace simbólico en cada componente del nombre dado de forma recursiva; todos menos el último componente deben existir —— Deman readlink


6

Stat le dará esta información:

$ stat current
  File: `current' -> `/home/user/releases/build/'
  ...

readlink realiza solo un paso para leer el enlace. por ejemplo en ubuntu tenemos / bin / zsh, que está enlazado a / etc / Alternatives / zsh, pero este es el segundo enlace simbólico. Finalmente, no obtendremos la ruta real del archivo o directorio. Lo mismo es con el comando stat. Solo el enlace de lectura con la opción -f resuelve todo.
Znik

5

Puedes hacer

readlink -f `which command`

o puedes obtener algo similar en Linux con

stat `which command` | grep File

Si está agregando esto a un script, inspeccione el error. Si no desea ver el mensaje de error en el caso de que el enlace sym no esté allí, vaya con algo como

readlink -f "`which command`" 

stat y realink sin -f hacen solo un paso. entonces mejor llame a readlink -f.
Znik

3

Me gustaría utilizar realpath <symlink>.

Probablemente lo que llamas 'fuente' es el archivo 'objetivo' de acuerdo con el uso de ln:Usage: ln [OPTION]... [-T] TARGET LINK_NAME


Gracias ¡Esto funcionó a las mil maravillas! con Mac OSX! donde readlinkno lo corté ... estúpido mac. lol
JayRizzo

0

readlink -f 'which java' No funcionó para mí.

Pero esto hizo:

readlink -f $(which java)

3
No funcionó porque es `no '.. pero $()es mejor la práctica de todos modos.
Stephen Rauch

¿Por qué downvote? Mi respuesta es una alternativa aceptable y, como dice el comentario, una mejor práctica.
NonCreature0714

1
La mayoría de las personas que votan en contra no hacen comentarios, por lo que pedir una explicación de un voto en contra rara vez le dará una explicación, porque el votante en contra ya se fue y es probable que no regrese. Le sugiero que elimine el código escrito que no funciona de su respuesta. Estaría dispuesto a votar si te tomaras el tiempo de limpiarlo y explicar por qué $()es una mejor práctica.
Stephen Rauch

Como Stephen te explicó, 'no es'. Debe encapsular por command, pero esto está en desuso. usar $ () es mejor, porque la encapsulación $ ($ (comando)) es mucho más fácil y no necesita un escape especial. Entonces se prefiere. En su primer ejemplo, usó el apóstrofe habitual, luego readlink está tratando de encontrar el archivo llamado 'which java' con espacio en su nombre. Pero su intención es llamar al comando que con el argumento java, para encontrar la ruta ejecutable binaria java.
Znik

0

En MAC OX, el parámetro "-f" no funciona, 'readlink' funciona sin ningún parámetro.

KZs-MacBook-Pro:bin kz$ readlink -f pip3
readlink: illegal option -- f
usage: readlink [-n] [file ...]

KZs-MacBook-Pro:bin kz$ readlink pip3
../../../Library/Frameworks/Python.framework/Versions/3.7/bin/pip3
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.