¿Cómo saber si realmente estoy en una ubicación de enlace simbólico desde la línea de comandos?

33

Supongamos que tengo una carpeta:

cd /home/cpm135/public_html

y hacer un enlace simbólico

ln -s /var/lib/class .

Más tarde, estoy en ese directorio:

cd /home/cpm135/public_html/class

El pwdme va a decir que estoy adentro/home/cpm135/public_html/class

¿Hay alguna manera de saber que estoy "realmente" dentro /var/lib/class? Gracias

Oliver Williams
fuente
1
Algunos shells en realidad no te permiten estar dentro de un enlace simbólico. Por ejemplo, el fishshell resuelve automáticamente el enlace simbólico cuando ingresas cden él.
trysis

Respuestas:

56

Dependiendo de cómo pwdesté configurado su comando, puede mostrar de manera predeterminada el directorio de trabajo lógico (salida por pwd -L) que mostrará la ubicación del enlace simbólico, o el directorio de trabajo físico (salida por pwd -P) que ignora el enlace simbólico y muestra el directorio "real".

Para información completa puedes hacer

file "$(pwd -L)"

Dentro de un enlace simbólico, esto devolverá

/path/of/symlink: symbolic link to /path/of/real/directory
Zanna
fuente
1
Sí, la -Pbandera era lo que necesitaba. Gracias
Oliver Williams
66
Para responder también la pregunta en el título, simplemente use test "$(pwd -L)" = "$(pwd -P)" && echo No symlinks(o reemplace && echo No symlinkscon || echo Symlinks).
un CVn
1
Esto responde la pregunta perfectamente sin la necesidad de hacer eco. ? Si la pregunta era '¿Cómo puedo mostrar un mensaje si estoy en un directorio del enlace simbólico", entonces el eco que se requeriría.
Arronical
file "$(pwd)"solo funciona si el enlace simbólico es el último componente del directorio. No detecta el enlace simbólico del OP cuando está en CD /home/cpm135/public_html/class/foo/bar. No conozco nada que imprima información para todos los enlaces simbólicos en un nombre de ruta, pero también puede usar realpath ., lo que creo que es equivalente apwd -P
Peter Cordes
17

Tenga en cuenta que en pwdrealidad es un shell incorporado. Dependiendo de su shell y su configuración, los resultados pueden cambiar. Para una solución más portátil, debe usar /bin/pwd. Fragmento de la página del manual:

NAME
       pwd - print name of current/working directory

SYNOPSIS
       pwd [OPTION]...

DESCRIPTION
       Print the full filename of the current working directory.

       -L, --logical
              use PWD from environment, even if it contains symlinks

       -P, --physical
              avoid all symlinks

       --help display this help and exit

       --version
              output version information and exit

       If no option is specified, -P is assumed.

       NOTE:  your  shell  may  have  its  own  version of pwd, which usually supersedes the version described here.  Please refer to your shell's documentation for
       details about the options it supports.

En general, puede resolver la ruta canónica completa de cualquier archivo / directorio utilizando readlink -f. readlink -f .funciona de forma similar a pwd -P.

Gowtham
fuente
2
Aunque he aprendido por las malas que readlink -fno está disponible en todos los Unices (por ejemplo, no está disponible en OS-X)
hasta el
3

Realmente estás en /home/cpm135/public_html/class , esa es la única respuesta correcta a la pregunta "cuál es mi directorio de trabajo actual".

Cuando se refiere a /var/lib/class... no se trata realmente de dónde se encuentra, sino más bien de qué camino solía llegar allí .

Cuando corres /bin/pwd , calcula su directorio de trabajo actual mirando el. y ... directorios (los que figuran en la parte superior de ls -la), que determinan con qué directorio ... coincide. y luego trabajando hacia atrás hasta ... y. consulte el mismo directorio. Una vez hecho todo eso, sabe cuál es su directorio de trabajo actual.

Cuando ejecuta el pwdshell incorporado, no sigue este procedimiento (aunque podría hacer algo si es necesario); en cambio, recuerda el camino que tomó para llegar aquí. Entonces cada vez que haces uncd comando, tu shell recuerda eso como parte del camino para llegar a donde estás ahora, e pwdimprime lo que ha calculado en función de todos los cdcomandos que has hecho, que pueden o no ser tu directorio de trabajo.

Las cosas pueden ponerse realmente extrañas cuando haces ln -s . fooy sigues cden foo: /bin/pwddirá que todavía estás en el mismo directorio, pero el shell incorporado pwddirá que estás en él /foo/foo/foo/foo/foo/foo, a pesar de que tal directorio realmente no existe. (Dicho esto, probablemente puedas cd hacerlo).

Otra fuente de confusión es si los directorios cambian de nombre. /bin/pwdluego recogerá el cambio de inmediato, pero el incorporado pwdno lo hará hasta que haga algo que le diga que el antiguo nombre del directorio no importa.

dougmc
fuente
1
No estás respondiendo la pregunta, la estás descartando.
Dmitry Grigoryev
44
Si bien esto no responde la pregunta directamente , creo que es una publicación útil para comprender la diferencia entre la pwdconstrucción integrada del shell /bin/pwdy explicar cómo la versión independiente proporciona información más útil (que puede responder a la pregunta original).
Anthony G - justicia para Monica
1
Estas diferencias todas se reducen a la -Py -Lopciones mencionadas por otras respuestas. En resumen, algunas implementaciones predeterminadas a una, algunas a la otra. En el sistema Centos que tengo a mano, el valor predeterminado de bash es lógico y /bin/pwdfísico, pero ambos aceptan las dos opciones de línea de comandos y acuerdan el resultado cuando se les da.
IMSoP
1
La pregunta se basa en una premisa incorrecta: "¿hay alguna forma de saber que estoy" realmente "en / var / lib / class?" Dicho esto ... al explicar lo que eso realmente significa, lo ayuda a comprender lo que realmente está buscando. Las opciones pwd -P y -L ya se habían mencionado ...
dougmc
1
Tienes tu argumento al revés. ls ..mostrará el contenido de /var/lib, no /home/cpm135/public_html. cd ..es especial: el shell realiza un seguimiento especial de "cómo llegó allí" y en realidad no realiza una chdir("..")llamada al sistema. En lo que respecta al núcleo, el directorio de trabajo actual de su shell ( /proc/self/cwd) es solo un punto de montaje: par de inodo. Es como un descriptor de archivo abierto en el directorio, por lo que renombrar el directorio no rompe su shell. ( cd .para actualizar la $PWDvariable del shell ). Estás haciendo un punto útil, así que votaría sobre esto cuando esté arreglado
Peter Cordes
1

Básicamente, está preguntando si hay que mostrar la ruta real del directorio de trabajo actual. Bueno, hay con python y os.getcwd()función

Lo que ve a continuación es una pequeña prueba desde el directorio "VirtualBox VMs" ubicado en mi directorio de inicio. En realidad, es un enlace simbólico a un directorio diferente ubicado en un disco duro diferente, montado en /mnt/HDD.

bash-4.3$ file "$(pwd)"
/home/xieerqi/VirtualBox VMs: symbolic link to /mnt/HDD/VirtualBox VMs/
bash-4.3$ python -c 'import os; print os.getcwd()'
/mnt/HDD/VirtualBox VMs

Como puede ver, Python os.getcwd()resuelve la ruta real del directorio, no la ruta del enlace simbólico.

Sergiy Kolodyazhnyy
fuente