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