Можно ли использовать "/" в имени файла? - PullRequest
92 голосов
/ 24 марта 2012

Я знаю, что это не то, что когда-либо должно быть сделано, но есть ли способ использовать символ косой черты, который обычно разделяет каталоги внутри имени файла в Linux?

Ответы [ 6 ]

118 голосов
/ 24 марта 2012

Ответ в том, что вы не можете, если в вашей файловой системе нет ошибки. И вот почему:

Для переименования файла, определенного в fs/namei.c, существует системный вызов с именем renameat:

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

Когда вызывается системный вызов, он выполняет поиск пути (do_path_lookup) по имени. Продолжайте отслеживать это, и мы получаем link_path_walk, который имеет это:

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

Этот код применяется к любой файловой системе. Что это значит? Это означает, что если вы попытаетесь передать параметр с действительным символом '/' в качестве имени файла с использованием традиционных средств, он не будет выполнять то, что вы хотите. Нет способа убежать от персонажа. Если файловая система «поддерживает» это, это потому, что они либо:

  • Используйте символ Unicode или что-то, что выглядит как косая черта, но не так.
  • У них есть ошибка.

Кроме того, если вы сделали , войдите и отредактируете байты для добавления символа косой черты в имя файла, могут произойти плохие вещи. Это потому, что вы никогда не можете ссылаться на этот файл по имени :(, поскольку в любое время Linux предполагал, что вы ссылаетесь на несуществующий каталог. Использование метода 'rm *' также не будет работать, поскольку bash просто расширяет его до имени файла. Даже rm -rf не сработает, так как простая полоска показывает, как все происходит под капотом (сокращено):

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

Обратите внимание, что эти вызовы unlinkat не будут выполнены, потому что они должны ссылаться на файлы по имени.

31 голосов
/ 24 марта 2012

Вы можете использовать символ Unicode, который отображается как «/» (например, этот, казалось бы, избыточный глиф ), если ваша файловая система поддерживает его.

7 голосов
/ 24 марта 2012

Это зависит от того, какую файловую систему вы используете. Из некоторых наиболее популярных:

4 голосов
/ 24 марта 2012

Только с согласованной кодировкой.Например, вы можете согласиться с тем, что % будет кодироваться как %%, а %2F будет означать /.Все программное обеспечение, которое получило доступ к этому файлу, должно понимать кодировку.

1 голос
/ 24 марта 2012

Короткий ответ: нет, вы не можете.Это необходимый запрет из-за того, как определяется структура каталогов.

И, как уже упоминалось, вы можете отображать символ Юникода, который «выглядит как» косая черта, но это так далеко, как вы получите.

0 голосов
/ 22 апреля 2015

Вообще это плохая идея пытаться использовать «плохие» символы в имени файла вообще;даже если вы каким-то образом управляете этим, это может затруднить последующее использование файла.Разделитель файловой системы полностью не работает, поэтому вам нужно будет выбрать альтернативный метод.

Рассматривали ли вы кодирование URL-адреса, а затем использовали его в качестве имени файла?Результат должен соответствовать имени файла, и его легко восстановить по кодированной версии.

Другой вариант - создать индекс - создать выходное имя файла, используя любой метод, который вам нравится - имена с последовательной нумерацией,Хэши SHA1, что угодно - тогда напишите файл с сгенерированной парой имя файла / URL.Вы можете сохранить это в хеше и использовать его для поиска URL-адреса к имени файла или наоборот с обращенной версией хэша, и вы можете записать его и перезагрузить позже, если необходимо.

...