¿Es posible usar “/” en un nombre de archivo?

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

La respuesta es que no puede, a menos que su sistema de archivos tenga un error. Este es el por qué:

Hay una llamada al sistema para cambiar el nombre de su archivo definido en fs/namei.c llamado renameat :

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

Cuando se invoca la llamada al sistema, realiza una búsqueda de ruta ( do_path_lookup ) en el nombre. Sigue rastreando 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 quiera. No hay forma de escapar del personaje. Si un sistema de archivos “admite” esto, es porque:

  • Use un carácter Unicode o algo que se parezca a una barra, pero no lo es.
  • Ellos tienen un error.

Además, si ingresas y editas los bytes para agregar un carácter de barra en un nombre de archivo, sucederán cosas malas. 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 funcionaría, ya que una simple estrategia revela cómo se desarrollan las cosas bajo el capó (abreviado):

 $ 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 ... 

Tenga en cuenta que estas llamadas a unlinkat fallarían porque necesitan referirse a los archivos por su nombre.

Podría usar un carácter Unicode que se muestre como “/” (por ejemplo, este glifo aparentemente redundante ) suponiendo que su sistema de archivos lo admite.

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

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

  • ext3: no
  • ext4: no
  • jfs: Sí
  • reiserfs: No
  • xfs: no

En general, es una mala idea tratar de usar caracteres “malos” 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.

¿Has considerado URL-encoding de la URL y luego usar eso como el nombre de 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 del archivo de salida utilizando el método que desee, nombres con numeración secuencial, 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.

La respuesta corta es: No, no puedes. 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.