กฎไวยากรณ์พา ธ


10

ฉันกำลังเขียนไลบรารีสำหรับจัดการสตริงเส้นทาง Unix ในกรณีนี้ฉันต้องเข้าใจบางส่วนที่ไม่ชัดเจนของไวยากรณ์ที่คนส่วนใหญ่ไม่ต้องกังวล

ตัวอย่างเช่นดีที่สุดเท่าที่ฉันสามารถบอกได้ดูเหมือนว่าfoo/barและfoo//barทั้งสองชี้ไปยังสถานที่เดียวกัน

นอกจากนี้~มักจะหมายถึงไดเรกทอรีบ้านของผู้ใช้ แต่ถ้ามันปรากฏขึ้นกลางเส้นทาง? จะเกิดอะไรขึ้น?

คำถามอื่น ๆ ที่คลุมเครือเหล่านี้และอีกหลายโหลต้องตอบถ้าฉันจะเขียนโค้ดที่จัดการทุกกรณีที่เป็นไปได้อย่างถูกต้อง ไม่มีใครรู้ถึงการอ้างอิงที่ชัดเจนซึ่งอธิบายกฎไวยากรณ์ที่แน่นอนสำหรับสิ่งนี้หรือไม่?

(น่าเสียดายที่การค้นหาคำเช่น "Unix path syntax" จะมีหน้าเว็บหลายล้านหน้าที่พูดถึง$PATHตัวแปร ... Heck ฉันกำลังดิ้นรนเพื่อหาแท็กที่เหมาะสมสำหรับคำถามนี้!)


การขยายตัว ok ~ tilde และ -filename เป็นคุณสมบัติ POSIX ที่กำหนดไว้พื้นฐานของสภาพแวดล้อม Unix เคล็ดลับ: ชื่อไฟล์สามารถเป็นอะไรก็ได้ยกเว้น \ 0 หรือ / ////// และ / เป็นสิ่งเดียวกัน $ PWD ได้รับการจัดการในเคอร์เนลและสามารถอ่านได้สำหรับกระบวนการใด ๆ(Linux)ใน / proc /./ สามารถเพียงเกิดขึ้นที่รากของเส้นทาง ใน $ PATH ::::: และ: เป็นสิ่งเดียวกัน / dev / null / dev / tty และ / tmp เป็นเส้นทางที่รับประกัน POSIX สำหรับทุกระบบที่เป็นไปตามข้อกำหนด
mikeserv

1
ส่วนใหญ่ของคำถามของคุณ ( แต่ไม่ใช่ส่วนหนึ่งเกี่ยวกับ~) จะครอบคลุมในวิธีลินุกซ์จับหลายแยกเส้นทาง (home / ชื่อผู้ใช้ //// /// ไฟล์) สิ่งที่ใกล้เคียงที่สุดกับการอ้างอิงเชิงบรรทัดฐานคือ POSIX หรือสเปค Unix เดียว - ไม่ใช่การอ่านที่ง่าย
Gilles 'หยุดความชั่วร้าย'

คำตอบ:


13

เส้นทางมีสามประเภท:

  • ทางญาติชอบfoo, foo/bar, ,../a .พวกเขาไม่ได้ขึ้นต้นด้วย/และสัมพันธ์กับไดเรกทอรีปัจจุบันของกระบวนการที่ทำการเรียกระบบด้วยเส้นทางนั้น
  • เส้นทางแน่นอนชอบ/, หรือ/foo/bar ///xพวกเขาเริ่มต้นด้วย 1 หรือ 3 หรือมากกว่า/พวกเขาไม่ได้ญาติจะค้นหาเริ่มต้นจาก/ไดเรกทอรีราก
  • POSIX อนุญาตให้//fooได้รับการปฏิบัติเป็นพิเศษ แต่ไม่ได้ระบุวิธี บางคนใช้ระบบว่าสำหรับกรณีพิเศษเช่นไฟล์เครือข่าย จะต้องมีการทับ 2 ครั้ง

นอกเหนือจากตอนเริ่มต้นลำดับของเครื่องหมายทับจะทำหน้าที่คล้ายกัน

~พิเศษสำหรับเชลล์เท่านั้นมันขยายโดยเชลล์ไม่ใช่พิเศษสำหรับระบบเลย การขยายตัวขึ้นอยู่กับเชลล์ เชลล์ทำการขยายรูปแบบอื่น ๆ เช่น globbing ( *.txt) หรือการขยายตัวแปร/$foo/$barหรืออื่น ๆ เท่าที่ระบบเกี่ยวข้อง~fooเป็นเพียงเส้นทางสัมพัทธ์เช่น_foofooหรือ

สิ่งที่ควรคำนึงถึง:

  • foo/fooไม่ได้เป็นเช่นเดียวกับ มันใกล้foo/.กว่าfoo(โดยเฉพาะถ้าfooเป็น symlink) สำหรับการเรียกใช้ระบบส่วนใหญ่ในระบบส่วนใหญ่ ( foo//เหมือนกันfoo/)
  • a/b/../cไม่จำเป็นต้องเหมือนกับa/c(เช่นถ้าa/bเป็น symlink) ที่ดีที่สุดคือไม่ต้องรักษา..เป็นพิเศษ
  • มันปลอดภัยโดยทั่วไปที่จะต้องพิจารณาa/././././bเช่นเดียวกับa/bว่า

ดังนั้นในการสรุปถ้าผมไม่สนใจเกี่ยวกับการจัดการเส้นทางเปลือก (ซึ่งมีมากมายและซับซ้อน) ผมจะต้องดูแลเกี่ยวกับ/, .และ..(?)
MathematicalOrchid

ตัวอย่างของ//fooการจัดการที่อยู่ใน Cygwin ซึ่งจะใช้สำหรับเส้นทาง UNC นั่นคือ//server/share/dir/file.txtเป็นเส้นทางที่ถูกต้องตามกฎหมายซึ่งเป็นจุดเริ่มต้น Cygwin serverไม่ถอยกลับไปดูที่ระบบท้องถิ่นถ้ามันไม่สามารถหา
Warren Young

3

ตัวอย่างเช่นดีที่สุดที่ฉันบอกได้ดูเหมือนว่า foo / bar และ foo // bar ทั้งคู่ชี้ไปที่สถานที่เดียวกัน

ใช่. นี่เป็นเรื่องปกติเพราะบางครั้งซอฟต์แวร์เชื่อมต่อเส้นทางที่สมมติว่าส่วนแรกไม่ได้ถูกยกเลิกด้วยเครื่องหมายทับ (forward slash) ดังนั้นจึงมีการโยนเพื่อให้แน่ใจว่า (อาจหมายถึงมีสองคนขึ้นไป) foo///barและยังชี้ไปที่สถานที่เดียวกันเป็นfoo/////bar foo/barฟังก์ชั่นที่ดีสำหรับห้องสมุดการจัดการเส้นทางจะเป็นหนึ่งซึ่งจะลดจำนวนสแลคลำดับใด ๆ ให้เป็นหนึ่ง (ยกเว้นที่จุดเริ่มต้นของเส้นทางซึ่งอาจใช้ในวิธี URL-ish หรือตามที่สเตฟานชี้ให้เห็น วัตถุประสงค์พิเศษที่ไม่ระบุ)

นอกจากนี้ ~ มักจะหมายถึงไดเรกทอรีบ้านของผู้ใช้

การแปลงนั้นกระทำผ่านเชลล์และการจ่ายตัวหนอนซึ่งใช้งานได้ถ้ามันเป็นตัวอักษรตัวแรกในเส้นทาง คุณจำเป็นต้องจัดการกับสิ่งนี้หรือไม่นั้นขึ้นอยู่กับบริบท หากห้องสมุดจะใช้กับโปรแกรมปกติที่ได้รับเช่นอาร์กิวเมนต์บรรทัดคำสั่งที่มีเส้นทางการขยายตัวหนอนจะทำเสร็จแล้วเมื่อพวกเขาเห็นเส้นทาง สถานการณ์เดียวที่ฉันเห็นว่าเป็นเรื่องที่น่ากังวลก็คือถ้าคุณกำลังประมวลผลเส้นทางโดยตรงจากไฟล์ข้อความ

นอกเหนือจากนั้น~เป็นตัวละครที่ถูกกฎหมายในเส้นทาง * ระวังและไม่ควรเปลี่ยนเป็นอย่างอื่น ด้วยเหตุนี้อักขระเฉพาะที่ไม่ถูกกฎหมายในชื่อไฟล์ยูนิกซ์คือ/(เพราะเป็นตัวแยกพา ธ ) และ "null" (aka. ไบต์ศูนย์) เพราะพวกมันผิดกฎหมายในข้อความโดยทั่วไป


+1 สำหรับคำอธิบายของการขยายตัวหนอน ฉันไม่รู้ว่าคุณสามารถอ้างถึงผู้ใช้รายอื่นด้วย!
คณิตศาสตร์

2
ดังที่สเตฟานกล่าวว่าคุณไม่สามารถยุบทับหน้าสแลชซ้ำทั้งหมดได้ ต้องใช้เครื่องหมายทับซ้ายหลายจุดที่จุดเริ่มต้นของเส้นทางอย่างระมัดระวัง
Warren Young

@WarrenYoung แก้ไขเพื่อให้ชัดเจน PS ไปข้างหน้า ??! O_O
goldilocks

ดีกว่า แต่ฉันจะไม่บอกว่าสิ่งนี้เกี่ยวข้องกับ URL UNC กลับไปสู่ช่วงปลายทศวรรษ 1980 ในขณะที่ URL ไม่ปรากฏจนกระทั่งหลายปีต่อมา
Warren Young

@WarrenYoung ยุติธรรมพอถึงแม้ว่ามันจะดูเหมือนว่า UNC นั้นมีความเฉพาะเจาะจงกับแพลตฟอร์ม MSดังนั้นใน//ทางเทคนิคก็ไม่ได้เป็นเช่นนั้น URL ทั้งสองและใหม่กว่า POS-to-SC ที่ไม่ชัดเจนสำหรับข้อมูลจำเพาะ POSIX สำหรับ// อาจได้มาจากสิ่งนี้ซึ่งในกรณีนี้ "URL-ish" ดูเหมือนว่าเป็นฉลาก apt สำหรับการประชุม (แม้ว่า UNCs จะเก่ากว่าและแม้ว่าจะมีรูปร่างหน้าตา ไม่ได้ตั้งใจ) ฉันจะไม่พูดว่า "พวกเขาเป็น URLS" เพียงอย่างเดียว//หรือ\\ เพื่อวัตถุประสงค์ "URL-ish"
goldilocks
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.