Odpowiedź brzmi, że nie możesz, chyba że twój system plików ma błąd. Dlatego:
Jest to wywołanie systemowe dla zmiany nazwy pliku zdefiniowanego w fs/namei.c
nazywa renameat
:
SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
int, newdfd, const char __user *, newname)
Kiedy wywołanie systemowe zostaje wywołane, wyszukuje ścieżkę ( do_path_lookup
) w nazwie. Śledź to, a dojdziemy do link_path_walk
tego:
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;
...
Ten kod ma zastosowanie do dowolnego systemu plików. Co to znaczy? Oznacza to, że jeśli spróbujesz przekazać parametr z rzeczywistym '/'
znakiem jako nazwę pliku przy użyciu tradycyjnych środków, nie zrobi on tego, co chcesz. Nie ma sposobu na ucieczkę od postaci. Jeśli system plików „obsługuje” to, dzieje się tak dlatego, że:
- Użyj znaku Unicode lub czegoś, co wygląda jak ukośnik, ale nim nie jest.
- Mają błąd.
Ponadto, jeśli nie iść i edytować bajtów dodać znak ukośnik w nazwie pliku, złe rzeczy się stanie. To dlatego, że nigdy nie możesz odwołać się do tego pliku po nazwie :( ponieważ kiedykolwiek to zrobiłeś, Linux założyłby, że odnosisz się do nieistniejącego katalogu. Używanie techniki „rm *” również nie zadziała, ponieważ bash po prostu rozszerza to do nazwy pliku. Nawet rm -rf
by nie zadziałało, ponieważ prosty pasek pokazuje, jak się dzieje pod maską (skrócony):
$ 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
...
Zauważ, że te wywołania unlinkat
zakończyłyby się niepowodzeniem, ponieważ muszą odnosić się do plików według nazwy.