Cevap, dosya sisteminizde bir hata olmadığı sürece yapamayacağınızdır. İşte nedeni:
Dosyanızın yeniden adlandırılması için fs/namei.c
çağrıda tanımlanan bir sistem çağrısı var renameat
:
SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
int, newdfd, const char __user *, newname)
Sistem çağrısı çağrıldığında, do_path_lookup
ad üzerinde bir yol araması ( ) yapar. Bunu izlemeye devam edin ve link_path_walk
hangisinin buna sahip olduğunu anlıyoruz :
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;
...
Bu kod, herhangi bir dosya sistemi için geçerlidir. Bunun anlamı nedir? Bu '/'
, dosyanın adı olarak gerçek bir karaktere sahip bir parametreyi geleneksel araçları kullanarak iletmeye çalışırsanız , istediğinizi yapmayacağı anlamına gelir. Karakterden kaçmanın bir yolu yok. Bir dosya sistemi bunu "destekliyorsa", bunun nedeni:
- Unicode karakter veya eğik çizgiye benzeyen ancak olmayan bir şey kullanın .
- Bir böcekleri var.
Eğer Dahası, yaptığımız bir dosya adı içine eğik çizgi karakteri eklemek ve düzenlemek bayt gidin kötü şeyler olacağını. Bunun nedeni, bu dosyaya asla isminizle atıfta bulunamayacağınız içindir :( yaptığınız her seferinde, Linux varolmayan bir dizine atıfta bulunduğunuzu varsayacaktır. 'Rm *' tekniğini kullanmak da işe yaramaz, çünkü bash bunu dosya adı olarak genişletir. Hatta rm -rf
işe yaramazdı, çünkü basit bir adım işlerin kaputun altında nasıl gittiğini gösteriyor (kısaltılmış):
$ 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
Dosyalara isimleriyle başvurmaları gerektiğinden bu çağrıların başarısız olacağına dikkat edin .