Чи можна використовувати "/" у назві файлу?


111

Я знаю, що це не те, що коли-небудь слід робити, але чи існує спосіб використання косої риси, яка зазвичай розділяє каталоги в імені файлу в Linux?


1
Я думаю, ви можете змінити ім'я файлу, використовуючи прямий доступ до свого розділу жорсткого диска та виправлення в символі '/' десь. Що трапляється - цікаве запитання ... швидше за все, не те, що ви хочете.
hochl

1
Але коротка відповідь повинна бути: ні, це не те, що коли-небудь слід робити :-)
Симеон Віссер

Чи є злом косою рискою на ім'я файлу у записі каталогу у FS? Це не рекомендується; ви не зможете отримати доступ до файлу ніколи.
Джонатан Леффлер

35
Це нагадує мені про час, коли мій друг створив файл з іменем, *а потім запитав: "Як я видалити файл?" Я відповів, rmа за ім'ям файлу. Ну, ви знаєте решта.
Девід Геффернан

1
Для нових користувачів Linux, коли ви не впевнені у виразі чи імені файлів, я вважаю, що корисно використовувати lsперелік файлів, які ви хочете видалити, а потім змінити lsкоманду на rmпотім.
Дейв Ф

Відповіді:


129

Відповідь полягає в тому, що ви не можете, якщо у вашій файловій системі немає помилки. Ось чому:

Існує система виклику для перейменування файлу , певного в 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не вдалося, оскільки їм потрібно посилатися на файли по імені.


8
Також зауважте, що принаймні e2fsckрозглядає будь-яке ім'я файлу як незаконне ім'я файлу, яке потрібно виправити - див. Джерело . Тож якщо ви якось узагальнюєте ім'я файлу з косою рисою, можете fsckвирішити проблему.
ehabkost

4
@ehabkost Будь-яке ім'я файлу? Звучить помилка e2fsck: p
flarn2006

36

Ви можете використовувати символ Unicode, який відображається як "/" (наприклад, цей, здавалося б, зайвий гліф ), якщо ваша файлова система підтримує його.


42
Так, саме: SOLIDUSзаборонено лише / /, що є U + 002F . Є багато інших відповідних кандидатів: ⁄ - U + 2044 FRACTION SLASH; ∕ - U + 2215 DIVISION SLASH; ⧸ є U + 29F8 BIG SOLIDUS; / Є U + FF0F FULLWIDTH SOLIDUS, а ╱ є U + 2571 є BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT. Все працювало б чудово!
tchrist

2
Але що робити, якщо користувач використовує ці фактичні символи у своїх іменах файлів / dir? Нам потрібне загальне рішення, що втече. Занадто поганий звичайний код Linux не підтримує жодного, оскільки він буквально відповідає ASCII 0x2F. ASCII - це велике "ні", щонайменше 20 років. (Unicode 1.0 - це з 1991 року!)
Evi1M4chine

@tchrist я вважаю за краще не залежати від unicode. тож я б, мабуть, віддав перевагу розмежувачам із кількома символами ---. у вашому виборі деліметрів можна використовувати інший символ та змінювати кількість повторень.
Тревор Бойд Сміт

Список можливих замін на численних персонажів, які заборонені в різних файлових системах, погляньте на мою відповідь: stackoverflow.com/a/61448658/4575793
Cadoiz

9

Це залежить від того, яку файлову систему ви використовуєте. З деяких більш популярних:


1
це не залежить тільки від файлової системи, системні виклики у всіх * nix системах будуть аналізувати / як компонент дерева каталогів.
Блекл Морі

2
Символ нахилу косої риски прямо кодується в ядро, незалежно від файлової системи (спробуйте зробити це grep -r "'/'" *у вашому джерелі ядра)
Роберт Мартін

20
@tchrist Вибачте. "Перекидання вперед" є цілком прийнятним способом посилання на символ косою косою рисою, щоб чітко зрозуміти, до котрої косої риси відноситься. Іноді люди плутаються: Р
Роберт Мартін

2
Га, але у @tchrist також є сенс, я думаю. Чому вперед "означає" / "і" назад "означає" \ "? Найкраще пояснення, яке я маю до цих пір, - це те, що якщо писати пером, починаючи з рядка, знизу вгору, '/' рухається вправо або вперед і '\' рухається 'вліво' або 'назад', коли читаєш / пишеш зліва направо. Мені не дуже подобається це пояснення, хоча частково тому, що я не завжди пишу своїх персонажів знизу і рухаюся вгору. Я думаю, що починати зверху і рухатися вниз під час написання персонажа часто протікає краще.
Джессі В. Коллінз

4
@jwso Це абсолютно побічна точка, але це стандартна, канонічна мова. Косою рисою не є те, що unicode називає символами, схожими на ці, вони називають їх солідусом, але "\" - це зворотний солідус, який є синонімом зворотного шляху, отже, і зворотній косої риси. Але якщо потрібне обгрунтування, назад і вперед - це напрямок, на який нахиляється лінія або має падати, з напрямком, заснованим на напрямку написання (зліва направо). Він нахиляється або повинен падати <== або назад, якщо він виглядає як "\", і ==> або вперед, якщо він виглядає як "/".
Стюарт Р. Джефферріс

4

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


19
"те, що ми називаємо косою рисою будь-яким іншим ім'ям, пахне бідно" - Шекспір
Роберт Мартін

1

Коротка відповідь: Ні, ви не можете. Це необхідна заборона через те, як визначена структура каталогу.

І, як згадувалося, ви можете відобразити символ унікоду, який "схожий" на косу рису, але це настільки, наскільки ви отримаєте.


1

Взагалі погана ідея взагалі намагатися використовувати "погані" символи у назві файлу; навіть якщо ви якимось чином керуєте ним, це, як правило, ускладнить використання файлу пізніше. Розділювач файлової системи взагалі не працює, тому вам потрібно буде вибрати альтернативний метод.

Чи розглядали ви, що кодує URL-адресу, використовуючи її як ім'я файлу? Результат повинен бути чудовим як ім'я файлу, і легко відновити ім’я з кодованої версії.

Інший варіант - створити індекс - створити назву вихідного файла за допомогою будь-якого способу, який вам подобається - послідовно пронумеровані імена, хеши SHA1, будь-який інший - потім запишіть файл із створеною паролем імені / URL-адреси. Ви можете зберегти це в хеш і використовувати його для пошуку URL-адреси на ім’я файлу або навпаки з переверненою версією хеша, і ви можете виписати його та перезавантажити пізніше, якщо потрібно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.