2012-03-23 2 views
70

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

+2

Какая файловая система? – Nicolas

+1

Я думаю, вы можете изменить имя файла, используя прямой доступ к вашему разделу жесткого диска и патчу в символе '/' где-нибудь. Что происходит, это интересный вопрос ... скорее всего, не то, что вы хотите. – hochl

+1

Но короткий ответ должен быть: нет, это не то, что должно было быть сделано :-) –

ответ

93

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

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

+4

Также обратите внимание, что по крайней мере 'e2fsck' считает любое имя файла как незаконное имя файла, которое должно быть исправлено - [см. Источник] (http://git.kernel.org/?p=fs/ ext2/e2fsprogs.git; а = блоб; е = e2fsck/pass2.C# l455). Поэтому, если вы каким-то образом закончите с именем файла, в котором есть косые черты, вы можете использовать 'fsck' для устранения проблемы. – ehabkost

26

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

+25

Да, точно: только /, что U + 002F 'SOLIDUS', запрещено. Есть много других подходящих кандидатов:/U + 2044 'FRACTION SLASH';/U + 2215 'DIVISION SLASH'; ⧸ U + 29F8 'BIG SOLIDUS';/Является U + FF0F 'FULLWIDTH SOLIDUS', а ╱ U + 2571 -« КОРОБКИ ЧЕРТЕЖЕЙ СВЕТОВОЙ ДИАГОНАЛЬНОЙ ВЕРХНЕЙ ПРАВО НА НИЖНЕЙ ВЛЕВО ». Все будут работать превосходно! – tchrist

+0

Но что, если пользователь использует эти фактические символы в своих именах файлов/dir? Нам нужно общее решение для экранирования. Слишком плохой обычный код Linux не поддерживает, так как он буквально совпадает с ASCII 0x2F. ASCII - большой нет-нет, по крайней мере, 20 лет. (Unicode 1.0 с 1991!) – Evi1M4chine

0

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

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

4

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

+13

«то, что мы называем косой чертой любым другим именем, будет пахнуть как фол» - Shakespeare –

3

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

+1

не зависит только от файловой системы, системные вызовы во всех системах * nix будут анализировать/как компонент дерева каталогов. –

+0

Символ прямой косой черты жестко закодирован в ядро, независимо от файловой системы (попробуйте выполнить команду 'grep -r" '/' "*' в вашем исходном коде ядра) –

+0

@RobertMartin «Вперед» слэш ??? – tchrist

1

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

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

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

Смежные вопросы