Hacer un enlace simbólico a una ruta relativa

64

Puedo hacer esto:

$ pwd
/home/beau
$ ln -s /home/beau/foo/bar.txt /home/beau/bar.txt
$ readlink -f bar.txt
/home/beau/foo/bar.txt

Pero me gustaría poder hacer esto:

$ pwd
/home/beau
$ cd foo
$ ln -s bar.txt /home/beau/bar.txt
$ readlink -f /home/beau/bar.txt
/home/beau/foo/bar.txt

es posible? ¿Puedo de alguna manera resolver el nombre de ruta relativo y pasarlo ln?

Humphrey Bogart
fuente
Pero, ¿cuál es el problema que se resolvería con el comportamiento descrito?
forcefsck
Bueno, supongamos que ofrece una carpeta comprimida para descargar y le gustaría dar instrucciones copiables sobre cómo vincular algunos de los archivos de la carpeta.
Humphrey Bogart
2
ln -s $(pwd)/bar.txt ~/o incluir un script de instalación.
forcefsck
2
el enlace almacena realmente el nombre que usa en la línea de comando. La resolución de ese nombre a un archivo se realiza en relación con la ubicación del enlace. Tienes que usarln -s foo/bar.txt /home/beau/bar.txt
pqnet

Respuestas:

62

Si crea un enlace simbólico a una ruta relativa, lo almacenará como un enlace simbólico relativo, no absoluto como muestra su ejemplo. Esto generalmente es algo bueno. Los enlaces simbólicos absolutos no funcionan cuando el sistema de archivos está montado en otro lugar.

La razón por la que su ejemplo no funciona es que es relativo al directorio padre del enlace simbólico y no a dónde lnse ejecuta.

Tu puedes hacer:

$ pwd
/home/beau
$ ln -s foo/bar.txt bar.txt
$ readlink -f /home/beau/bar.txt
/home/beau/foo/bar.txt

O para eso importa:

$ cd foo
$ ln -s foo/bar.txt ../bar.txt

Es importante darse cuenta de que el primer argumento posterior ln -sse almacena como el objetivo del enlace simbólico. Puede ser cualquier cadena arbitraria (con las únicas restricciones de que no puede estar vacía y no puede contener el carácter NUL), pero en el momento en que se usa y resuelve el enlace simbólico, esa cadena se entiende como una ruta relativa al directorio padre del enlace simbólico (cuando no comienza con /).

pingüino359
fuente
2
Bien dicho. Respondiste esto mientras escribía mi propia respuesta. :)
Shadur
Acabo de tener una pregunta ligeramente diferente, y esto la responde perfectamente. Quería saber cómo hacer referencia al directorio de inicio en el enlace simbólico para que funcionara cuando lo transfiriera de un usuario a otro. No estaba seguro si algo así ~funcionaría.
Joe
"esa cadena se entiende como una ruta relativa al directorio padre del enlace simbólico" - ¡esto lo explica todo!
Bojan Komazec
24

Si usa coreutils más nuevos (estoy usando coreutils-8.22-11), tiene una opción para hacerlo:

ln --help | grep relative

puede contener texto arbitrario; si luego se resuelve, un enlace relativo es -r, --relativo crea enlaces simbólicos relativos a la ubicación del enlace

Por ejemplo:

$ mkdir /tmp/test
$ touch /tmp/test/to
$ ln -rs /tmp/test/to /tmp/test/from
$ ls -l /tmp/test/from
    lrwxrwxrwx 1 ptr ptr 4 aug   25 17.02 /tmp/test/to -> from
ptr
fuente
Hm, para mí parece que no hay tal opción -r. Sin embargo, usando Mac.
ivkremer
1
@ivkremer parece que esta opción está disponible desde coreutils> = 8,16 (fuente: superuser.com/a/837935/403979 )
DJCrashdummy
El uso de la bandera relativa parecía aclarar los problemas de "demasiados niveles de enlaces simbólicos" que estaba experimentando.
Vix
12

Lo siento, no. Los enlaces simbólicos son relativos a la ubicación en la que se encuentra el enlace, no a la ubicación en la que se encontraba cuando creó el enlace. Hay varias buenas razones para este comportamiento, la mayoría de las cuales implican montar sistemas de archivos remotos.

Shadur
fuente
7

Hay una pequeña utilidad conveniente llamada symlinks(originalmente por Mark Lords, ahora mantenida por J. Brandt Buckley), presente en muchas distribuciones de Linux.

Para convertir todos los enlaces simbólicos absolutos en un directorio para que sean relativos:

symlinks -c /path/to/directory

Lamentablemente, no hay una opción para convertir un solo enlace, primero debería moverlo a su propio directorio.

mkdir ../tmp
mv link-to-relativize ../tmp
symlinks ../tmp
mv ../tmp/* .
rmdir ../tmp
Gilles 'SO- deja de ser malvado'
fuente
Gracias. enlaces simbólicos disponibles en github . Mantenido por J. Brandt Buckley. v1.4.3 .
Evgeny Vereshchagin
3

Tu podrías intentar:

ln -s `pwd`/bar.txt /home/beau/bar.txt

Pero, hace un enlace simbólico al nombre de ruta absoluto. Su pregunta textual pregunta menciona nombre de ruta relativo ...

Normalmente, un nombre de ruta relativo es lo que desea y lo que ln -sle proporciona. Creo que lo que quieres es:

cd /home/beau
ln -s foo/bar.txt bar.txt
MattBianco
fuente
1

A medida que los shells más comunes expanden las rutas, para crear un enlace simbólico relativo, debe citar la "ruta de origen".

Además, el -sparámetro significa --symbolic. lncrea enlaces duros por defecto.

$ ln -s '../../relative_path' path
$ ls -al path

lrwxrwxrwx 1 empjustine empjustine 19 Aug  6 01:38 path -> ../../relative/path
emp.justine
fuente
0

Si está seguro de que no hay posibilidad de que sus puntos de montaje cambien, puede lograr lo que está tratando de hacer en un shell de bash como este:

ln -s `pwd`/bar.txt ~/bar.txt

Esto supone que usted está en el directorio de destino al hacer el enlace simbólico.

mreff555
fuente