Digamos que inicio sesión en un shell en un sistema Unix y empiezo a tocar comandos. Inicialmente comienzo en el directorio de inicio de mi usuario ~
. Podría desde allí cd
hasta el directorio Documents
.
El comando para cambiar el directorio de trabajo aquí es muy simple de entender intuitivamente: el nodo primario tiene una lista de nodos secundarios a los que puede acceder, y presumiblemente usa una variante (optimizada) de una búsqueda para localizar la existencia de un nodo secundario con el nombre del usuario ingresado, y el directorio de trabajo se "modifica" para que coincida con esto - corríjame si me equivoco allí. Incluso puede ser más simple que el shell simplemente intente "ingenuamente" intentar acceder al directorio exactamente según los deseos del usuario y cuando el sistema de archivos devuelve algún tipo de error, el shell muestra una respuesta en consecuencia.
Sin embargo, lo que me interesa es cómo funciona el mismo proceso cuando navego por un directorio, es decir, a un padre o al padre de un padre.
Dada mi ubicación desconocida, presumiblemente "ciega" Documents
, de uno de los muchos directorios posibles en todo el árbol del sistema de archivos con ese nombre, ¿cómo determina Unix dónde debería ubicarme a continuación? ¿Hace referencia pwd
y examina eso? En caso afirmativo, ¿cómo pwd
rastrea el estado de navegación actual?
fuente
Respuestas:
Las otras respuestas son simplificaciones excesivas, cada una presenta solo partes de la historia, y están equivocadas en un par de puntos.
Hay dos formas en que se rastrea el directorio de trabajo:
chdir()
yfchdir()
la segunda porchroot()
. Uno puede verlos indirectamente en/proc
los sistemas operativos Linux o mediante elfstat
comando en FreeBSD y similares:Cuando funciona la resolución de nombre de ruta, comienza en uno u otro de los vnodos referenciados, según si la ruta es relativa o absoluta. (Hay una familia de
…at()
llamadas al sistema que permiten que la resolución de la ruta comience en el vnodo al que hace referencia un descriptor de archivo abierto (directorio) como tercera opción).En microkernel Unices, la estructura de datos está en el espacio de aplicación, pero el principio de mantener referencias abiertas a estos directorios sigue siendo el mismo.
chdir()
.Si uno cambia a un nombre de ruta relativo, manipula la cadena para agregar ese nombre. Si uno cambia a un nombre de ruta absoluto, reemplaza la cadena con el nuevo nombre. En ambos casos, ajusta la cadena para eliminar
.
y..
componentes y para perseguir enlaces simbólicos reemplazándolos con sus nombres vinculados. ( Aquí está el código del shell Z para eso , por ejemplo).El nombre en la variable de cadena interna es rastreado por una variable de shell llamada
PWD
(ocwd
en los shells C). Esto se exporta convencionalmente como una variable de entorno (denominadaPWD
) a los programas generados por el shell.Estos dos métodos de cosas de seguimiento son reveladas por los
-P
y las-L
opciones alcd
epwd
incorporada en el shell comandos, y por las diferencias entre las conchas incorporadospwd
comandos y tanto el/bin/pwd
comando y el incorporado enpwd
los comandos de cosas como (entre otros) VIM y NeoVIM.Como puede ver: obtener el directorio de trabajo "lógico" es una cuestión de mirar la
PWD
variable de shell (o la variable de entorno si no se trata del programa de shell); mientras que obtener el directorio de trabajo "físico" es cuestión de llamar a lagetcwd()
función de biblioteca.La operación del
/bin/pwd
programa cuando-L
se usa la opción es algo sutil. No puede confiar en el valor de laPWD
variable de entorno que ha heredado. Después de todo, no es necesario que haya sido invocado por un shell y los programas que intervienen pueden no haber implementado el mecanismo del shell para hacer que laPWD
variable de entorno siempre rastree el nombre del directorio de trabajo. O alguien puede hacer lo que hice allí.Entonces, lo que hace es (como dice el estándar POSIX) verificar que el nombre dado
PWD
arroje lo mismo que el nombre.
, como se puede ver con un seguimiento de llamada del sistema:Como puede ver: solo llama
getcwd()
si detecta una falta de coincidencia; y se puede engañar estableciendoPWD
una cadena que de hecho nombre el mismo directorio, pero por una ruta diferente.La
getcwd()
función de biblioteca es un tema en sí mismo. Pero para precisar:..
directorio. Se detuvo cuando llegó a un bucle donde..
era el mismo que su directorio de trabajo o cuando hubo un error al intentar abrir el siguiente..
. Esto sería una gran cantidad de llamadas al sistema bajo las sábanas.Sin embargo, tenga en cuenta que incluso en FreeBSD y esos otros sistemas operativos, el núcleo no realiza un seguimiento del directorio de trabajo con una cadena.
Navegar
..
nuevamente es un tema en sí mismo. Otro précis: aunque los directorios convencionalmente (aunque, como ya se mencionó, esto no es obligatorio) contienen una..
estructura de datos de directorio real en el disco, el kernel rastrea el directorio padre de cada vnode de directorio y, por lo tanto, puede navegar al..
vnode de cualquier directorio de trabajo. Esto es algo complicado por el punto de montaje y los mecanismos raíz modificados, que están más allá del alcance de esta respuesta.Aparte
Windows NT, de hecho, hace algo similar. Hay un único directorio de trabajo por proceso, establecido por la
SetCurrentDirectory()
llamada API y rastreado por proceso por el núcleo a través de un identificador de archivo abierto (interno) a ese directorio; y hay un conjunto de variables de entorno que los programas Win32 (no solo los intérpretes de comandos, sino todos los programas Win32) usan para rastrear los nombres de múltiples directorios de trabajo (uno por unidad), agregándolos o sobrescribiéndolos cada vez que cambian de directorio.Convencionalmente, a diferencia del caso de los sistemas operativos Unix y Linux, los programas Win32 no muestran estas variables de entorno a los usuarios. Sin embargo, a veces se pueden ver en subsistemas similares a Unix que se ejecutan en Windows NT, así como al usar los comandos de los intérpretes de
SET
comandos de una manera particular.Otras lecturas
pwd
" . The Open Group Base Especificaciones Número 7. IEEE 1003.1: 2008. El grupo abierto. 2016fuente
..
en el contexto del Plan9,.
y..
componentes y para perseguir enlaces simbólicos reemplazándolos con sus nombres vinculados. ... El nombre en la variable de cadena interna es rastreado por una variable de shell llamadaPWD
... "(énfasis agregado). … (Continúa)PWD
=…/b
después de uncd b
comando, aunqueb
es un enlace simbólico aa
- para que el shell no "persiga" ela -> b
enlace. ¿Has dicho mal o he leído mal?CHASE_LINKS
.El núcleo no realiza un seguimiento de los nombres de directorio o archivo; un archivo o directorio está representado en el núcleo por un par inodo / dispositivo. Las llamadas al sistema como
chdir()
,open()
, etc. toman un camino como parámetro, que puede ser absoluta (por ejemplo/etc/passwd
), o en relación con el directorio actual (ejemplos:Documents
,..
). Cuando se ejecuta un procesochdir("Documents")
, se realiza una búsquedaDocuments
en el directorio de trabajo actual y el directorio de trabajo del proceso se actualiza para hacer referencia a este directorio. Desde la perspectiva del kernel, no hay nada especial en el nombre "..", es solo una convención en el sistema de archivos que se..
refiere al directorio padre.La
getcwd()
función no es una llamada al sistema, sino una función de biblioteca que debe abrirse camino hasta el directorio raíz, registrando los nombres de los componentes de la ruta en el camino.fuente
Curiosamente, tradicionalmente
cd ..
es mucho más simple quepwd
. Los directorios nombrados..
se colocan explícitamente en el sistema de archivos. El sistema realiza un seguimiento del dispositivo / inodo del directorio actual, por lo que,cd ..
o más exactamente, la llamada del sistemachdir("..")
solo implica buscar el nombre ".." en el archivo que pertenece al inodo del directorio actual y cambiar el dispositivo / inodo del directorio actual al valor encontrado allí.pwd
(con mayor precisión/bin/pwd
) sigue los..
enlaces sucesivamente y lee los directorios respectivos hasta encontrar el inodo de donde proviene, reuniendo la lista de esos nombres en reversa hasta que llega al directorio raíz (en particular, no contiene una..
entrada).Ahora este es el comportamiento básico original de bajo nivel. Los comandos de shell reales se
pwd
basan en una variedad de técnicas que almacenan en caché el nombre de ruta actual. Pero en el fondo, solo se conoce su inodo. Eso implica que una vez que los enlaces simbólicos se utilizan para navegar por los directorios, las nociones de nombre del directorio de trabajo actual del shell actual y del sistema/bin/pwd
pueden divergir.fuente