เป็นไปได้ไหมที่จะใช้“ /” ในชื่อไฟล์


111

ฉันรู้ว่านี่ไม่ใช่สิ่งที่ควรทำ แต่มีวิธีใช้อักขระสแลชที่ปกติแยกไดเร็กทอรีภายในชื่อไฟล์ใน Linux หรือไม่?


1
ฉันเดาว่าคุณสามารถแก้ไขชื่อไฟล์โดยใช้การเข้าถึงโดยตรงไปยังพาร์ติชันฮาร์ดดิสก์ของคุณและแก้ไขในอักขระ '/' ที่ใดที่หนึ่ง สิ่งที่เกิดขึ้นเป็นคำถามที่น่าสนใจ ... ส่วนใหญ่อาจไม่ใช่สิ่งที่คุณต้องการ
hochl

1
แต่คำตอบสั้น ๆ ควรเป็น: ไม่นี่ไม่ใช่สิ่งที่ควรทำ :-)
Simeon Visser

การแฮ็กเครื่องหมายทับลงในชื่อไฟล์ในรายการไดเร็กทอรีใน FS นับหรือไม่ จะไม่แนะนำ คุณไม่สามารถเข้าถึงไฟล์ได้เลย
Jonathan Leffler

35
สิ่งนี้ทำให้ฉันนึกถึงเวลาที่เพื่อนตั้งชื่อไฟล์*แล้วถามว่า "ฉันจะลบไฟล์ได้อย่างไร" ฉันตอบrmตามด้วยชื่อไฟล์ คุณก็รู้ที่เหลือ
David Heffernan

1
สำหรับผู้ใช้ Linux ใหม่เมื่อคุณไม่มั่นใจเกี่ยวกับนิพจน์หรือชื่อไฟล์ฉันคิดว่าเป็นแนวทางปฏิบัติที่ดีที่จะใช้lsแสดงรายการไฟล์ที่คุณต้องการลบออกจากนั้นจึงเปลี่ยนlsคำสั่งในrmภายหลัง
Dave F

คำตอบ:


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

รหัสนี้ใช้กับระบบไฟล์ใด ๆ นี่หมายความว่าอย่างไร หมายความว่าหากคุณพยายามส่งผ่านพารามิเตอร์ที่มี'/'อักขระจริงเป็นชื่อของไฟล์โดยใช้วิธีการดั้งเดิมมันจะไม่ทำตามที่คุณต้องการ ไม่มีทางหนีพ้นตัวละคร หากระบบไฟล์ "รองรับ" สิ่งนี้อาจเป็นเพราะ:

  • ใช้อักขระ Unicode หรือสิ่งที่ดูเหมือนเครื่องหมายทับ แต่ไม่ใช่
  • พวกเขามีจุดบกพร่อง

นอกจากนี้ถ้าคุณไม่ไปในและแก้ไขไบต์เพื่อเพิ่มตัวอักษรทับลงไปในชื่อไฟล์สิ่งเลวร้ายที่จะเกิดขึ้น นั่นเป็นเพราะคุณไม่สามารถอ้างถึงไฟล์นี้ด้วยชื่อ :( ตั้งแต่เมื่อใดก็ตามที่คุณทำ 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 ที่แสดงเป็น "/" (ตัวอย่างเช่นสัญลักษณ์ที่ดูเหมือนซ้ำซ้อนนี้ ) โดยสมมติว่าระบบไฟล์ของคุณรองรับ


43
ใช่แน่นอน: 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 ---ดังนั้นฉันอาจจะชอบคั่นหลายตัวเช่น ตัวเลือกเส้นคั่นของคุณสามารถใช้อักขระอื่นและเปลี่ยนจำนวนการทำซ้ำได้
Trevor Boyd Smith

สำหรับรายการการแทนที่ที่เป็นไปได้สำหรับอักขระจำนวนมากซึ่งห้ามใช้ภายใต้ระบบไฟล์ที่แตกต่างกันโปรดดูคำตอบของฉัน: stackoverflow.com/a/61448658/4575793
Cadoiz

9

ขึ้นอยู่กับระบบไฟล์ที่คุณใช้ จากรายการยอดนิยมบางส่วน:


1
ไม่ได้ขึ้นอยู่กับระบบไฟล์เท่านั้นการเรียกระบบในระบบ * nix ทั้งหมดจะแยกวิเคราะห์ / เป็นส่วนประกอบของแผนผังไดเร็กทอรี
Blackle Mori

2
อักขระสแลชไปข้างหน้าถูกฮาร์ดโค้ดลงในเคอร์เนลโดยไม่ขึ้นกับระบบไฟล์ (ลองทำgrep -r "'/'" *ในแหล่งเคอร์เนลของคุณ)
Robert Martin

20
@tchrist ขอโทษนะ "เครื่องหมายทับ" เป็นวิธีที่ยอมรับได้โดยสิ้นเชิงในการอ้างถึงอักขระสแลชเพื่อให้ชัดเจนอย่างละเอียดว่าหมายถึงเครื่องหมายทับใด บางครั้งคนก็สับสน: P
Robert Martin

2
ฮ่า ๆ แต่ @tchrist ก็มีประเด็นเช่นกันฉันคิดว่า เหตุใดการส่งต่อ "หมายถึง" / "และ" ย้อนกลับ "จึงบ่งบอกถึง" \ " คำอธิบายที่ดีที่สุดที่ฉันมีคือถ้าเขียนด้วยปากกาโดยเริ่มจากบรรทัดจากล่างขึ้นบน '/' จะเลื่อนไปทางขวาหรือ 'ไปข้างหน้า' และ '\' ย้าย 'ซ้าย' หรือ 'ย้อนกลับ' เมื่ออ่าน / เขียน จากซ้ายไปขวา. ฉันไม่ชอบคำอธิบายนั้นจริงๆส่วนหนึ่งเป็นเพราะฉันไม่ได้เขียนตัวอักษรจากด้านล่างและเลื่อนขึ้น ฉันคิดว่าการเริ่มต้นจากด้านบนและเลื่อนลงในขณะที่เขียนตัวอักษรมักจะไหลได้ดีกว่า
Jesse W. Collins

4
@jwso นี่คือประเด็นด้านข้างโดยสิ้นเชิง แต่นี่เป็นมาตรฐานภาษาบัญญัติ Slash ไม่ใช่สิ่งที่ Unicode เรียกสัญลักษณ์ที่มีลักษณะเช่นนี้เรียกว่า solidus แต่ "\" เป็น reverse solidus ซึ่งมีความหมายเหมือนกันกับ backslash ดังนั้น backslash แต่ถ้าใครต้องการเหตุผลย้อนกลับและไปข้างหน้าคือทิศทางที่เส้นเอนหรือควรตกลงโดยมีทิศทางตามทิศทางการเขียน (ซ้ายไปขวา) มันเอนหรือควรตก <== หรือถอยหลังหากดูเหมือน "\" และ ==> หรือไปข้างหน้าหากมีลักษณะเป็น "/"
Stuart R.Jefferys

4

ด้วยการเข้ารหัสที่ตกลงกันเท่านั้น ตัวอย่างเช่นคุณสามารถตกลงว่า%จะเข้ารหัสเป็น%%และนั่น%2Fจะหมายถึงไฟล์/. ซอฟต์แวร์ทั้งหมดที่เข้าถึงไฟล์นี้จะต้องเข้าใจการเข้ารหัส


19
"สิ่งที่เราเรียกว่าสแลชด้วยชื่ออื่นจะมีกลิ่นเหม็น" - เช็คสเปียร์
โรเบิร์ตมาร์ติน

1

คำตอบสั้น ๆ คือไม่คุณทำไม่ได้ เป็นข้อห้ามที่จำเป็นเนื่องจากมีการกำหนดโครงสร้างไดเรกทอรี

และตามที่กล่าวไว้คุณสามารถแสดงอักขระ Unicode ที่ "ดูเหมือน" เครื่องหมายทับได้ แต่เท่าที่คุณจะได้รับ


1

โดยทั่วไปเป็นความคิดที่ดีที่จะพยายามใช้อักขระ "ไม่ดี" ในชื่อไฟล์เลย แม้ว่าคุณจะจัดการมัน แต่ก็มีแนวโน้มที่จะทำให้ยากต่อการใช้ไฟล์ในภายหลัง ตัวแยกระบบไฟล์ไม่ทำงานเลยดังนั้นคุณจะต้องเลือกวิธีอื่น

คุณได้พิจารณาการเข้ารหัส URL ของ URL แล้วใช้เป็นชื่อไฟล์หรือไม่? ผลลัพธ์ควรเป็นชื่อไฟล์และง่ายต่อการสร้างชื่อจากเวอร์ชันที่เข้ารหัส

อีกทางเลือกหนึ่งคือการสร้างดัชนี - สร้างชื่อไฟล์ที่ส่งออกโดยใช้วิธีใดก็ได้ที่คุณต้องการ - ชื่อที่เรียงตามลำดับแฮช SHA1 อะไรก็ได้ - จากนั้นเขียนไฟล์ด้วยคู่ชื่อไฟล์ / URL ที่สร้างขึ้น คุณสามารถบันทึกลงในแฮชและใช้ในการค้นหา URL เป็นชื่อไฟล์หรือในทางกลับกันด้วยแฮชเวอร์ชันที่กลับด้านและคุณสามารถเขียนและโหลดซ้ำในภายหลังได้หากจำเป็น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.