Apakah mungkin menggunakan "/" dalam nama file?

111

Saya tahu bahwa ini bukanlah sesuatu yang harus dilakukan, tetapi adakah cara untuk menggunakan karakter garis miring yang biasanya memisahkan direktori dalam nama file di Linux?

subcan
sumber
1
Saya kira Anda dapat mengubah nama file menggunakan akses langsung ke partisi hardisk Anda dan menambalnya dengan karakter '/' di suatu tempat. Apa yang terjadi adalah pertanyaan yang menarik ... kemungkinan besar bukan yang Anda inginkan.
hochl
1
Tetapi jawaban singkatnya seharusnya: tidak, ini bukan sesuatu yang harus dilakukan :-)
Simeon Visser
Apakah meretas garis miring ke nama file di entri direktori dalam hitungan FS? Itu tidak akan direkomendasikan; Anda tidak akan pernah dapat mengakses file tersebut.
Jonathan Leffler
35
Ini mengingatkan saya pada saat teman saya membuat file bernama *dan kemudian bertanya, "Bagaimana cara menghapus file?" Saya menjawab, rmdiikuti dengan nama file. Nah, Anda tahu sisanya.
David Heffernan
1
Untuk pengguna Linux baru, ketika Anda tidak yakin tentang ekspresi atau nama file, saya pikir itu praktik yang baik untuk digunakan lsuntuk membuat daftar file yang ingin Anda hapus dan kemudian mengubah lsperintah menjadi rmsesudahnya.
Dave F

Jawaban:

129

Jawabannya adalah Anda tidak bisa, kecuali sistem file Anda memiliki bug. Inilah alasannya:

Ada sistem panggilan untuk mengubah nama file Anda didefinisikan dalam fs/namei.cdisebut renameat:

SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
                int, newdfd, const char __user *, newname)

Saat panggilan sistem dipanggil, ia melakukan pencarian jalur ( do_path_lookup) pada namanya. Terus telusuri ini, dan kita sampai pada link_path_walkyang memiliki ini:

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;
...

Kode ini berlaku untuk sistem file apa pun. Apa maksudnya ini? Ini berarti bahwa jika Anda mencoba melewatkan parameter dengan '/'karakter aktual sebagai nama file menggunakan cara tradisional, itu tidak akan melakukan apa yang Anda inginkan. Tidak ada cara untuk melarikan diri dari karakter tersebut. Jika filesystem "mendukung" ini, itu karena mereka:

  • Gunakan karakter unicode atau sesuatu yang terlihat seperti garis miring tetapi bukan.
  • Mereka punya bug.

Selain itu, jika Anda melakukan masuk dan mengedit byte untuk menambahkan karakter garis miring menjadi nama file, hal-hal buruk akan terjadi. Itu karena Anda tidak pernah bisa merujuk ke file ini dengan nama :( karena kapan pun Anda melakukannya, Linux akan menganggap Anda merujuk ke direktori yang tidak ada. Menggunakan teknik 'rm *' juga tidak akan berhasil, karena bash hanya memperluasnya ke nama file. Bahkan rm -rftidak akan berhasil, karena strace sederhana mengungkapkan bagaimana segala sesuatunya berjalan di bawah tenda (disingkat):

$ 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
...

Perhatikan bahwa panggilan ke ini unlinkatakan gagal karena mereka perlu merujuk ke file menurut namanya.

Robert Martin
sumber
8
Juga, perhatikan bahwa setidaknya e2fsckmenganggap nama file apa pun sebagai nama file ilegal yang harus diperbaiki — lihat sumbernya . Jadi jika Anda entah bagaimana berakhir dengan nama file yang memiliki garis miring di dalamnya, Anda dapat menggunakan fsckuntuk memperbaiki masalah tersebut.
ehabkost
4
@ehabost Ada nama file? Kedengarannya seperti bug di e2fsck: p
flarn2006
36

Anda dapat menggunakan karakter Unicode yang ditampilkan sebagai "/" (misalnya mesin terbang yang tampaknya berlebihan ini ) dengan asumsi sistem file Anda mendukungnya.

Blackle Mori
sumber
42
Ya tepatnya: hanya /, yaitu U + 002F SOLIDUS, dilarang. Ada banyak kandidat lain yang cocok: ⁄ adalah U + 2044 FRACTION SLASH; ∕ adalah U + 2215 DIVISION SLASH; ⧸ adalah U + 29F8 BIG SOLIDUS; / Adalah U + FF0F FULLWIDTH SOLIDUS, dan ╱ adalah U + 2571 adalah BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT. Semuanya akan bekerja dengan mengagumkan!
tchrist
2
Tapi kemudian bagaimana jika pengguna menggunakan karakter sebenarnya di nama file / dirnya? Kami membutuhkan solusi pelarian generik. Kode normal Linux yang terlalu buruk tidak mendukung apa pun, karena benar-benar cocok dengan ASCII 0x2F. ASCII adalah larangan besar sejak setidaknya 20 tahun. (Unicode 1.0 adalah dari 1991!)
Evi1M4chine
@ tchrist saya memilih untuk tidak bergantung pada unicode. jadi saya mungkin lebih suka pembatas multi-karakter seperti ---. pilihan pembatas Anda dapat menggunakan karakter yang berbeda dan memvariasikan jumlah pengulangan.
Trevor Boyd Smith
Untuk daftar kemungkinan penggantian pada banyak karakter, yang dilarang di bawah sistem file yang berbeda, lihat jawaban saya: stackoverflow.com/a/61448658/4575793
Cadoiz
9

Itu tergantung pada filesystem apa yang Anda gunakan. Dari beberapa yang lebih populer:

Nicolas
sumber
1
tidak hanya bergantung pada sistem file, panggilan sistem di semua sistem * nix akan mengurai / sebagai komponen pohon direktori.
Blackle Mori
2
Karakter garis miring ke depan dikodekan dengan keras ke dalam kernel, terlepas dari sistem file (coba lakukan grep -r "'/'" *di sumber kernel Anda)
Robert Martin
20
@tp. Permisi. "Garis miring" adalah cara yang dapat diterima sepenuhnya untuk merujuk pada karakter garis miring untuk memperjelas garis miring mana yang diacu . Terkadang orang menjadi bingung: P
Robert Martin
2
Hah, tapi @tchrist juga ada benarnya, kurasa. Mengapa maju 'menyiratkan' / 'dan' kembali 'menyiratkan' \ '? Penjelasan terbaik yang saya miliki sejauh ini adalah jika ditulis dengan pena dimulai pada satu baris, dari bawah ke atas, '/' bergerak ke kanan atau 'maju' dan '\' bergerak 'ke kiri' atau 'kembali', saat membaca / menulis dari kiri ke kanan. Saya tidak terlalu suka penjelasan itu, sebagian karena saya tidak selalu menulis karakter saya dari bawah dan naik. Saya pikir mulai dari atas dan ke bawah sambil menulis karakter sering kali mengalir lebih baik.
Jesse W. Collins
4
@jwso Ini benar-benar poin samping, tapi ini adalah bahasa kanonik standar. Garis miring bukanlah simbol yang disebut unicode seperti ini, ia menyebutnya solidus, tetapi "\" adalah solidus terbalik, yang identik dengan mundur, karenanya garis miring terbalik. Namun bila membutuhkan pembenaran, maka ke belakang dan ke depan adalah arah garis miring atau harus turun, dengan arah sesuai dengan arah tulisan (kiri ke kanan). Ini miring atau harus jatuh <== atau ke belakang jika terlihat seperti "\", dan ==> atau ke depan jika terlihat seperti "/".
Stuart R. Jefferys
4

Hanya dengan pengkodean yang disepakati. Misalnya, Anda dapat menyetujui bahwa %akan dikodekan sebagai %%dan itu %2Fberarti a /. Semua perangkat lunak yang mengakses file ini harus memahami pengkodeannya.

David Schwartz
sumber
19
"yang kami sebut tebasan dengan nama lain akan berbau busuk" - Shakespeare
Robert Martin
1

Jawaban singkatnya adalah: Tidak, Anda tidak bisa. Ini adalah larangan yang diperlukan karena bagaimana struktur direktori didefinisikan.

Dan, seperti yang disebutkan, Anda dapat menampilkan karakter unicode yang "terlihat seperti" garis miring, tapi sejauh itu yang Anda dapatkan.

keyser
sumber
1

Secara umum adalah ide yang buruk untuk mencoba menggunakan karakter "buruk" dalam nama file sama sekali; bahkan jika Anda entah bagaimana mengelolanya, hal itu cenderung mempersulit penggunaan file nanti. Pemisah sistem file benar-benar tidak akan berfungsi sama sekali, jadi Anda harus memilih metode alternatif.

Pernahkah Anda mempertimbangkan pengkodean URL URL kemudian menggunakannya sebagai nama file? Hasilnya harus bagus sebagai nama file, dan mudah untuk merekonstruksi nama dari versi yang dikodekan.

Pilihan lainnya adalah membuat indeks - buat nama file keluaran menggunakan metode apa pun yang Anda suka - nama dengan nomor berurutan, hash SHA1, apa pun - lalu tulis file dengan pasangan nama file / URL yang dihasilkan. Anda dapat menyimpannya ke dalam hash dan menggunakannya untuk melakukan pencarian URL-ke-nama file atau sebaliknya dengan versi hash yang dibalik, dan Anda dapat menulisnya dan memuatnya kembali nanti jika diperlukan.

Joe McMahon
sumber