Можно ли использовать "/" в имени файла?

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

Ответ 1

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

Существует системный вызов для переименования вашего файла, определенного в 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;
...

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

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

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

$ 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 не будут работать, потому что они должны ссылаться на файлы по имени.

Ответ 2

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

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

И, как уже упоминалось, вы можете отобразить символ юникода, который "выглядит" как косая черта, но что касается вас.