Reglas de sintaxis de ruta

10

Estoy escribiendo una biblioteca para manipular cadenas de ruta Unix. Siendo ese el caso, necesito entender algunos rincones oscuros de la sintaxis de los que la mayoría de la gente no se preocuparía.

Por ejemplo, lo mejor que puedo decir, parece que foo/bary foo//barambos apuntan al mismo lugar.

Además, ~generalmente representa el directorio de inicio del usuario, pero ¿qué pasa si aparece en el medio de una ruta? ¿Qué pasa entonces?

Estas y varias docenas de otras preguntas oscuras necesitan respuesta si voy a escribir código que maneje todos los casos posibles correctamente. ¿Alguien sabe de una referencia definitiva que explique las reglas de sintaxis exactas para estas cosas?

(Desafortunadamente, la búsqueda de términos como "sintaxis de ruta de Unix" solo muestra un millón de páginas que discuten la $PATHvariable ... ¡Diablos, incluso estoy luchando por encontrar etiquetas adecuadas para esta pregunta!)

Orquídea matemática
fuente
ok ~ tilde y -filename expansion son características subyacentes definidas por POSIX de cualquier entorno Unix. Algunos consejos: un nombre de archivo puede ser cualquier cosa menos \ 0 o /. ////// y / son lo mismo. $ PWD se maneja en el núcleo y se puede leer para cualquier proceso (Linux) en / proc. /./ solo puede ocurrir en la raíz de una ruta. En $ PATH ::::: y: son lo mismo. / dev / null / dev / tty y / tmp son rutas garantizadas POSIX para cada sistema conforme.
mikeserv
1
La mayor parte de su pregunta (pero no la parte sobre ~) se trata en Cómo Linux maneja los separadores de múltiples rutas (/ home //// nombre de usuario /// archivo) . Lo más parecido a una referencia normativa sería la especificación POSIX o Single Unix , no es una lectura fácil.
Gilles 'SO- deja de ser malvado'

Respuestas:

13

Hay tres tipos de caminos:

  • rutas relativas como foo, foo/bar, ../a, .. No comienzan con /y son relativos al directorio actual del proceso que realiza una llamada al sistema con esa ruta.
  • rutas absolutas como /, /foo/baro ///x. Comienzan con 1, o 3 o más /, no son relativos, se buscan a partir del /directorio raíz.
  • POSIX permite //fooser tratado especialmente, pero no especifica cómo. Algunos sistemas lo usan para casos especiales como archivos de red . Tiene que ser exactamente 2 barras.

Aparte de al principio, las secuencias de barras actúan como una.

~solo es especial para el shell , está expandido por el shell, no es especial para el sistema en absoluto. Cómo se expande depende de la cáscara. Los proyectiles realizan otras formas de expansión como globbing ( *.txt) o expansión variable /$foo/$baru otras. En lo que respecta al sistema, ~fooes solo una ruta relativa como _fooo foo.

Cosas a tener en cuenta:

  • foo/No es lo mismo que foo. Está más cerca de foo/.que foo(especialmente si fooes un enlace simbólico) para la mayoría de las llamadas al sistema en la mayoría de los sistemas ( foo//es lo mismo que foo/aunque).
  • a/b/../cno es necesariamente lo mismo que a/c(por ejemplo, si a/bes un enlace simbólico). Lo mejor es no tratarlo ..especialmente.
  • En general, es seguro considerar a/././././blo mismo como a/bsi fuera.
Stéphane Chazelas
fuente
Así que en resumen, si no se preocupan por la manipulación ruta cáscara (que es enorme y complicado), sólo necesito que se preocupan por /, .y ..(?)
MathematicalOrchid
Un ejemplo de //foomanejo se encuentra en Cygwin, donde se usa para rutas UNC . Es decir, //server/share/dir/file.txtes una ruta legal que señala fuera del sistema por defecto. Cygwin recurre a mirar el sistema local si no puede encontrarlo server.
Warren Young
3

Por ejemplo, lo mejor que puedo decir, parece que foo / bar y foo // bar apuntan al mismo lugar.

Si. Esto es común porque el software a veces concatena una ruta suponiendo que la primera parte no se terminó con una barra diagonal, por lo que se lanza uno para asegurarse (lo que significa que puede terminar siendo dos o más). foo///bary foo/////bartambién apuntan al mismo lugar que foo/bar. Una buena función para una biblioteca de manipulación de rutas sería una que reduzca cualquier número de barras secuenciales a una (excepto al comienzo de una ruta, donde puede usarse de una manera URL-ish, o, como señala Stephane, para cualquier propósito especial no especificado).

Además, ~ generalmente representa el directorio de inicio del usuario

Esa transformación se realiza a través de la exapansión de shell y tilde , que solo funciona si es el primer personaje en el camino. Si necesita o no lidiar con esto depende del contexto. Si la biblioteca se va a usar con programas normales que reciben, por ejemplo, argumentos de la línea de comandos que contienen una ruta, la expansión de tilde ya está hecha cuando ven la ruta. La única situación que puedo ver que es preocupante es si está procesando rutas directamente desde un archivo de texto.

Más allá de eso, ~es un carácter legal en una ruta * nix y no debe cambiarse a otra cosa. Según esto , los únicos caracteres que no son legales en un nombre de archivo Unix son /(porque es el separador de ruta) y "nulo" (también conocido como un byte cero) porque generalmente son ilegales en el texto.

encerrada dorada
fuente
+1 para la explicación de la expansión de tilde; ¡No tenía idea de que podría referirse a otros usuarios con él!
MathematicalOrchid
2
Como dice Stephane, no puedes colapsar ciegamente todas las barras diagonales repetidas. Varias barras diagonales al inicio del camino deben tratarse con cuidado.
Warren Young
@WarrenYoung Editado para aclarar esto. PD. ¡¿¿Adelante??! O_O
goldilocks
Mejor, aunque no diría que esto tiene nada que ver con las URL. UNC se remonta a fines de la década de 1980, mientras que las URL no aparecieron hasta años después.
Warren Young
@WarrenYoung Lo suficientemente justo, aunque parece que los UNC son específicos de las plataformas de MS , por //lo que técnicamente tampoco es eso. Tanto URLS como la nueva especificación POSIX libremente ambigua de SC // pueden haberse derivado de la misma, en cuyo caso "URL-ish" parece una etiqueta adecuada para la convención (incluso si los UNC son más antiguos, e incluso si la apariencia no es intencional) Nunca diría que "son URLS", solo eso //o \\ sirve para un propósito "URL-ish".
Ricitos