He creado un enlace simbólico con ruta absoluta al directorio (Blink) y tengo, por ejemplo, el siguiente árbol:
$ ls -l /tmp/A
total 0
lrwxrwxrwx 1 root root 6 Apr 3 12:27 Blink -> /tmp/B
-rw-r--r-- 1 root root 0 Apr 3 12:27 foo
$ ls -l /tmp/B
total 0
-rw-r--r-- 1 root root 0 Apr 3 12:27 bar
luego voy a / tmp / A y cambio el directorio a Blink:
$ cd /tmp/A
$ pwd
/tmp/A
$ cd Blink
$ pwd
/tmp/A/Blink
cd ..
me devuelve a, /tmp/A
pero si escribo, por ejemplo ls ../foo
, obtendré un error:
ls: ../foo: No such file or directory
El comando cd incorporado resuelve la ruta según sea necesario, pero los ls externos consideran el .. como nivel superior de / tmp / B y, por lo tanto, no pueden encontrar foo.
¿Cuál es el problema aquí? ¿Puedo obtener el archivo foo de / tmp / A / Blink por una ruta relativa como ../foo?
Respuestas:
No creo que puedas hacer esto. Hoy en día, los shells realizan un seguimiento de cómo llegaron a donde están, hacen un seguimiento del directorio de trabajo actual por nombre, en lugar de depender únicamente del sistema de archivos y el sistema operativo para mantenerlo. Eso significa que la función incorporada
cd
puede "respaldar" el enlace simbólico, en lugar de simplemente seguir las cadenas ".." directamente.Pero cuando ejecuta
ls ../foo
,ls
no es consciente de que el shell llegó a un directorio siguiendo enlaces simbólicos.ls
hará unstat()
"../foo". La parte ".." proviene del directorio actual, que tiene una sola entrada ".." para su padre. Todo el enlace simbólico no cambia la forma en que los directorios tienen un solo "." y una sola entrada "..". Los enlaces simbólicos permiten que el núcleo inserte una capa adicional de indirección en las rutas de los archivos. Cuando se pasa "../whatever" aopen()
ostat()
, el núcleo sólo utiliza el directorio de trabajo actual del proceso de hacer la llamada para averiguar qué solo directorio es nombrado por "..".fuente
El shell almacena el directorio de trabajo actual en
$PWD
. Eso es lo que se usa para las cáscaras incorporadascd
ypwd
, como has visto, trata los enlaces simbólicos como directorios normales. A veces esto es útil, a veces no.Puede encontrar el directorio real usando
pwd
(escribahelp pwd
para obtener más detalles):Del mismo modo,
cd
tiene una opción-P
(de nuevo,help cd
es tu amigo):Finalmente, puede desactivar la "función" por completo:
fuente
set -P
y el comportamiento de ls comienzan a tener sentido. :)Bruce y ams dieron hermosas respuestas explicando el comportamiento detrás. Pero para hacer realmente lo
ls ../foo
que estabas pidiendo, podrías ir con algo comofuente
No puedes hacerlo, porque
/tmp/A/Blink
es en realidad/tmp/B
. Entonces,ls ../A/foo
funciona.En su lugar, puede resultarle útil poder cd al directorio real
/tmp/B
, en lugar del alias/tmp/A/Blink
. Para hacer eso, puede usar la siguiente función en lugar decd
(que puede poner en su .bashrc)lcd
, por supuesto, funciona tanto para directorios normales como para enlaces simbólicos.Nota:
readlink -f
actúa sobre el objetivo final del enlace (cuando los enlaces están en cadena).fuente
cd -P
parece más simple