¿El objetivo del enlace simbólico es relativo al directorio padre del destino y, de ser así, por qué?

14

Tengo la siguiente estructura de archivos:

build/
client/
  –> index.js

Y cuando trato de crear un enlace simbólico llamado "cliente" dentro del directorio de compilación que se refiere al directorio del cliente en el cwd así

// Fails
$ pwd
/home/user/
$ ln -s client build/client 
$ stat build/client/index.js
stat: build/client/index.js: stat: Too many levels of symbolic links

Me sale el error ELOOP que se muestra arriba. Cuando cambio la ruta de destino para que sea relativa a la ruta de destino, todo está bien:

// Works
$ pwd
/home/user/
$ ln -s ../client build/client 
$ stat build/client/index.js
stat: <outputs file stats>

¿Es este el comportamiento previsto y explique por qué ...

jibsales
fuente
esto probablemente tenga algo que ver con el hecho de que usar ../ usa la ruta absoluta para declarar la ruta en lugar de la ruta relativa. una buena práctica es usar siempre el camino absoluto
Kiwy
Estoy de acuerdo con la mejor práctica, ya que siempre he usado rutas absolutas para el destino y el destino. Sin embargo, las páginas man indican que las rutas relativas se pueden usar para ambos ...
jibsales

Respuestas:

13

Para el que no funciona, si miramos el ls -lresultado, obtenemos lo siguiente:

[sparticvs@sparta test]$ ls -l build/
total 0
lrwxrwxrwx. 1 sparticvs sparticvs 6 Dec 17 16:08 client -> client

Ahora para entender lo que está pasando aquí. Veamos el comando que llamaste:

ln -s client build/client

Según la página del manual, hay dos posibles coincidencias para este formato

SYNOPSIS
       ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
       ln [OPTION]... TARGET... DIRECTORY     (3rd form)

Coincidirá en la primera forma (desde su primera). Ahora, el "nombre de destino" o clienten su caso, pueden ser (según el lnmanual completo ) cadenas arbitrarias. No tienen que resolver nada en este momento, pero pueden resolver algo en el futuro. Lo que está creando con su invocación es un "enlace simbólico colgante" y el sistema no le impide crearlos.

Ahora su segunda invocación ln -s ../client build/clientes lo que se llama un "enlace simbólico relativo" (como señaló en su propia publicación). Hay un segundo tipo y es un "enlace simbólico absoluto" al que se llamaría haciendo ln -s /home/user/client build/client.

Esto no es un error. Según el manual dice:

Al crear un enlace simbólico relativo en una ubicación diferente al directorio actual, la resolución del enlace simbólico será diferente a la resolución de la misma cadena del directorio actual. Por lo tanto, muchos usuarios prefieren cambiar primero los directorios a la ubicación donde se creará el enlace simbólico relativo, para que la finalización de la pestaña u otra resolución de archivo encuentre el mismo objetivo que el que se colocará en el enlace simbólico.

-- desde info coreutils 'ln invocation'

Dicho esto, DEBE utilizar la ruta relativa o absoluta al objetivo.

sparticvs
fuente
5

Este es de hecho el comportamiento previsto. Desde la ln(1)página del manual:

Los enlaces simbólicos pueden contener texto arbitrario; si luego se resuelve, se interpreta un enlace relativo en relación con su directorio padre.

En cuanto a por qué, imagínese si el enlace simbólico se interpretara en lugar de su origen en lugar de su destino. Cuando más tarde lo resuelva, necesitará saber cuál era su CWD cuando lo creó, lo cual no tiene sentido, y mucho menos es imposible.

Además, de esta manera obtienes un método ordenado y compacto para crear una estructura de directorio esqueleto que puedes colocar en cualquier lugar del árbol de directorios sin romper los enlaces simbólicos.

Para darle un ejemplo de lo que quiero decir, supongamos que está trabajando en un proyecto y tiene una estructura de directorios completa configurada de esta manera:

$ ls -1 /home/you/project
thingummies/
widgets/
wizardry/

Ahora suponga que desea crear un enlace simbólico al widgets/interior wizardry/. Tienes dos opciones:

$ ln -s /home/you/project/widgets /home/you/project/wizardry

o

$ ln -s ../widgets /home/you/project/wizardry

Si luego intentas /home/you/projectmoverte a otro lugar, un enlace simbólico creado con el primer formulario se romperá porque está buscando /home/you/project/widgets. La segunda forma mantendrá el enlace simbólico funcional porque está buscando en ../widgets relación con el lugar en el que se encuentra, independientemente de dónde pueda estar ese lugar en el árbol de directorios.

Joseph R.
fuente