2012-03-23 28 views
70

Sé que esto no es algo que deba hacerse nunca, pero ¿hay alguna manera de usar el carácter de barra que normalmente separa los directorios dentro de un nombre de archivo en Linux?¿Es posible usar "/" en un nombre de archivo?

+2

¿Qué sistema de archivos? – Nicolas

+1

Supongo que puede modificar el nombre de un archivo mediante el acceso directo a la partición de su disco duro y el parche en un carácter '/' en algún lugar. Lo que sucede es una pregunta interesante ... muy probablemente no sea lo que quieres. – hochl

+1

Pero la respuesta corta debería ser: no, esto no es algo que deba hacerse alguna vez :-) –

Respuesta

93

La respuesta es que no puedes, a menos que tu sistema de archivos tenga un error. He aquí por qué:

No es una llamada al sistema para cambiar el nombre del archivo se define en fs/namei.c llamada renameat:

SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, 
       int, newdfd, const char __user *, newname) 

Cuando la llamada al sistema se invoca, se realiza una consulta de ruta (do_path_lookup) en el nombre. Mantenemos el rastreo esto, y llegamos a link_path_walk que tiene esto:

static int link_path_walk(const char *name, struct nameidata *nd) 
{ 
     struct path next; 
     int err; 
     unsigned int lookup_flags = nd->flags; 

     while (*name=='/') 
       name++; 
     if (!*name) 
       return 0; 
... 

Este código se aplica a cualquier sistema de archivos. ¿Que significa esto? Significa que si intenta pasar un parámetro con un carácter real '/' como el nombre del archivo utilizando los medios tradicionales, no hará lo que desee. No hay forma de escapar del personaje. Si un sistema de archivos "apoya" a esto, es porque o bien:

  • utilizar un carácter Unicode o algo que se ve como una barra, pero no lo es.
  • Tienen un error.

Por otra parte, si hizo entrar y editar los bytes añadir un carácter de barra en un nombre de archivo, las cosas malas que pasaría. Eso es porque nunca podrías referirte a este archivo por nombre :(ya que cada vez que lo hicieras, Linux asumiría que te referías a un directorio inexistente. Usar la técnica 'rm *' tampoco funcionaría, ya que bash simplemente expande eso al nombre del archivo.Incluso rm -rf no quiere trabajar, ya que un strace sencilla revela cómo van las cosas bajo el capó (acortados):

$ ls testdir 
myfile2 out 
$ strace -vf rm -rf testdir 
... 
unlinkat(3, "myfile2", 0)    = 0 
unlinkat(3, "out", 0)     = 0 
fcntl(3, F_GETFD)      = 0x1 (flags FD_CLOEXEC) 
close(3)        = 0 
unlinkat(AT_FDCWD, "testdir", AT_REMOVEDIR) = 0 
... 

en cuenta que estas llamadas a unlinkat fallarían debido a que necesitan para hacer referencia a los archivos por nombre.

+4

Además, tenga en cuenta que al menos 'e2fsck' considera cualquier nombre de archivo como un nombre de archivo ilegal que debe ser corregido- [ver la fuente] (http://git.kernel.org/?p=fs/ ext2/e2fsprogs.git; a = blob; f = e2fsck/pass2.C# l455). Entonces, si de alguna manera terminas con un nombre de archivo que tiene barras, puedes usar 'fsck' para solucionar el problema. – ehabkost

26

Puede usar un carácter Unicode que se muestre como "/" (por ejemplo this seemingly redundant glyph) suponiendo que su sistema de archivos lo admite.

+25

Sí, precisamente: solo /, que es U + 002F 'SOLIDUS', está prohibido. Hay muchos otros candidatos adecuados:/es U + 2044 'FRACTION SLASH';/Es U + 2215 'DIVISION SLASH'; ⧸ es U + 29F8 'BIG SOLIDUS';/Es U + FF0F 'FULLWIDTH SOLIDUS', y ╱ es U + 2571 es' BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT PARA BAJAR A LA IZQUIERDA '. ¡Todo funcionaría admirablemente! – tchrist

+0

Pero, ¿qué ocurre si el usuario usa esos caracteres reales en sus nombres de archivo/directorio? Necesitamos una solución de escape genérica. Lástima que el código normal de Linux no admite ninguno, ya que literalmente coincide en ASCII 0x2F. ASCII es un gran no-no desde hace al menos 20 años. (¡Unicode 1.0 es de 1991!) – Evi1M4chine

0

La respuesta corta es: No, no se puede. Es una prohibición necesaria debido a cómo se define la estructura del directorio.

Y, como se mencionó, puede mostrar un carácter Unicode que "se parece" a una barra inclinada, pero eso es todo lo que obtiene.

4

Solo con una codificación acordada. Por ejemplo, puede aceptar que % se codificará como %% y que %2F significará /. Todo el software que accedió a este archivo debería comprender la codificación.

+13

"lo que llamamos una barra oblicua con cualquier otro nombre huele a asqueroso" - Shakespeare –

3

Depende de qué sistema de archivos está utilizando. De algunos de los más populares:

+1

no depende solo del sistema de archivos, las llamadas al sistema en todos los sistemas * nix analizarán el/como un componente del árbol de directorios. –

+0

El carácter de barra inclinada está codificado en el kernel, independientemente del sistema de archivos (intente hacer 'grep -r" '/' "*' en la fuente de su kernel) –

+0

@RobertMartin Barra "hacia adelante" ??? – tchrist

1

En general, es una mala idea tratar de utilizar caracteres "incorrectos" en un nombre de archivo; incluso si de alguna manera lo administra, tiende a dificultar el uso del archivo más adelante. El separador del sistema de archivos no funcionará en absoluto, por lo que tendrá que elegir un método alternativo.

¿Ha considerado la URL codificar la URL y usarla como el nombre del archivo? El resultado debería estar bien como nombre de archivo, y es fácil reconstruir el nombre de la versión codificada.

Otra opción es crear un índice: cree el nombre de archivo de salida utilizando el método que desee: nombres numerados secuencialmente, hashes SHA1, lo que sea, y luego escriba un archivo con el par de nombre de archivo/URL generado. Puede guardarlo en un hash y usarlo para realizar una búsqueda de URL a archivo o viceversa con la versión inversa del hash, y puede escribirlo y volver a cargarlo más adelante si es necesario.

Cuestiones relacionadas