¿El destino de symlink es relativo al directory padre del destino y, de ser así, por qué?

Tengo la siguiente estructura de file:

build/ client/ –> index.js 

Y cuando trato de crear un enlace simbólico llamado "cliente" dentro del directory de compilation que hace reference al directory del cliente en el cwd como tal

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

Aparece 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 por favor explica por qué …

Para el que no funciona, si miramos el resultado ls -l , 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 command que llamaste:

 ln -s client build/client 

De acuerdo con la página de manual, hay dos posibles coincidencias para este formatting

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

Coincidirá en la primera forma (desde la primera). Ahora, el "nombre de destino" o client en su caso, puede ser (de acuerdo con el manual completo en ln ) 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/client es lo que se denomina un "enlace simbólico relativo" (como anotó en su propia publicación). Hay un segundo tipo y es un "enlace simbólico absoluto" que se llamaría haciendo ln -s /home/user/client build/client .

Esto no es un error. De acuerdo con el manual, dice:

Al crear un enlace simbólico relativo en una location diferente a la del directory actual, la resolución del enlace simbólico será diferente a la resolución de la misma cadena del directory actual. Por lo tanto, muchos usuarios prefieren cambiar primero los directorys a la location donde se creará el enlace simbólico relativo, de modo que la resolución de tabulación u otra resolución de file encuentre el mismo objective que lo que se colocará en el enlace simbólico.

– de info coreutils 'ln invocation'

Dicho esto, DEBE usar la ruta relativa o absoluta al objective.

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

Los enlaces simbólicos pueden contener text arbitrario; si se resuelve más tarde, se interpreta un vínculo relativo en relación con su directory padre.

En cuanto al por qué, imagina si el enlace simbólico se interpretara en lugar de su origen en lugar de su destino. Cuando más tarde lo resolviera, necesitaría saber cuál era su CWD cuando lo creó, lo cual es imposible, y mucho less sin sentido.

Además, de esta manera obtienes un método limpio y compacto para crear una estructura de directory esqueleto que puedes colocar en cualquier parte del tree de directorys sin romper los enlaces simbólicos.

Para darte un ejemplo de lo que quiero decir, digamos que estás trabajando en un proyecto y tienes toda una estructura de directorys configurada para ello de la siguiente manera:

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

Ahora supongamos que quiere crear un enlace simbólico a widgets/ dentro de wizardry/ . Tienes dos opciones:

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

o

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

Si luego intenta mover /home/you/project 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 ../widgets relativos al lugar donde se encuentra, independientemente de dónde esté ese lugar en el tree de directorys.