ทำไมฉันถึงแมว / dev?


41

ฉันสามารถcat /devฉันสามารถผมไม่สามารถls /dev less /devเหตุใดจึงcatให้catไดเรกทอรีนี้ แต่ไม่มีไดเรกทอรีอื่น ๆ

รูปภาพของพฤติกรรมนี้ใน zsh


@ KamilMaciorowski นี่คือผลลัพธ์และneofetchสำหรับข้อมูลของคุณ :) i.imgur.com/3azpnDt.png
haboutnnah

คำตอบ:


43

ในอดีต (มากถึง V7 UNIX หรือประมาณปี 1979) การreadเรียกระบบทำงานได้ทั้งไฟล์และไดเรกทอรี readในไดเรกทอรีจะส่งคืนโครงสร้างข้อมูลอย่างง่ายซึ่งโปรแกรมผู้ใช้จะแยกวิเคราะห์เพื่อรับรายการไดเรกทอรี อันที่จริงlsเครื่องมือV7 ทำสิ่งนี้อย่างแน่นอน - readในไดเรกทอรีให้แยกโครงสร้างข้อมูลผลลัพธ์ออกในรูปแบบรายการที่มีโครงสร้าง

ในฐานะที่เป็นระบบไฟล์ที่มีความซับซ้อนมากขึ้นนี้ "ง่าย" โครงสร้างข้อมูลมีความซับซ้อนมากขึ้นเพื่อจุดที่ฟังก์ชั่นห้องสมุดถูกเพิ่มเข้าไปในโปรแกรมความช่วยเหลือในการแยกวิเคราะห์การส่งออกของreaddir read(directory)ระบบและระบบไฟล์ที่แตกต่างกันอาจมีรูปแบบบนดิสก์ที่ต่างกันซึ่งมีความซับซ้อน

เมื่อซันแนะนำระบบไฟล์เครือข่าย (NFS) พวกเขาต้องการทำให้โครงสร้างไดเรกทอรีบนดิสก์เป็นนามธรรมอย่างสมบูรณ์ แทนที่จะread(directory)ส่งคืนการแสดงไดเรกทอรีโดยไม่ขึ้นกับแพลตฟอร์ม แต่พวกเขาเพิ่มการเรียกระบบใหม่getdirents- และถูกแบนreadในไดเรกทอรีที่ติดตั้งบนเครือข่าย การเรียกใช้ระบบนี้ได้รับการปรับให้ทำงานกับไดเรกทอรีทั้งหมดในรสชาติ UNIX ที่หลากหลายอย่างรวดเร็วทำให้เป็นวิธีเริ่มต้นในการรับเนื้อหาของไดเรกทอรี (ประวัติย่อจากhttps://utcc.utoronto.ca/~cks/space/blog/unix/ReaddirHistory )

เพราะreaddirตอนนี้เป็นวิธีเริ่มต้นในการอ่านไดเรกทอรีread(directory)โดยทั่วไปจะไม่ได้รับการดำเนินการ (กลับ - EISDIR) บน OSE ที่ทันสมัยที่สุด (QNX เป็นต้น) เป็นข้อยกเว้นที่น่าสังเกตซึ่งใช้readdirเป็นread(directory)) อย่างไรก็ตามด้วยการออกแบบ "ระบบไฟล์เสมือน" ในเมล็ดที่ทันสมัยที่สุดมันเป็นจริงขึ้นอยู่กับแต่ละระบบไฟล์ว่าการอ่านไดเรกทอรีใช้งานได้หรือไม่

และแน่นอนว่าใน macOS devfsระบบไฟล์ที่รองรับ/devmountpoint นั้นรองรับการอ่านได้จริง ( https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/bsd/miscfs/devfs_vnops.c#L629 ) :

static int
devfs_read(struct vnop_read_args *ap)
{
        devnode_t * dn_p = VTODN(ap->a_vp);

    switch (ap->a_vp->v_type) {
      case VDIR: {
          dn_p->dn_access = 1;

          return VNOP_READDIR(ap->a_vp, ap->a_uio, 0, NULL, NULL, ap->a_context);

สิ่งนี้เรียกอย่างชัดเจนREADDIRหากคุณพยายามอ่าน/dev(การอ่านไฟล์ภายใต้/devได้รับการจัดการโดยฟังก์ชั่นแยกต่างหาก - devfsspec_read) ดังนั้นหากโปรแกรมเรียกใช้การreadเรียกระบบ/devมันจะประสบความสำเร็จและรับรายชื่อไดเรกทอรี!

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


น่าจะเป็นหลังเห็นว่ามันถูกลบออกจากไดเรกทอรีส่วนใหญ่
user253751

36

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

เหตุใด OS จึงอนุญาตให้catเปิดไดเรกทอรี ตามธรรมเนียมในระบบสไตล์ BSD ไดเรกทอรีทั้งหมดสามารถอ่านเป็นไฟล์และนั่นคือวิธีที่โปรแกรมจะแสดงรายการไดเรกทอรีในตอนแรก: เพียงแค่ตีความโครงสร้างไดเรนท์ที่เก็บไว้ในดิสก์

ต่อมาโครงสร้างบนดิสก์เหล่านั้นเริ่มแตกต่างจาก dirent ที่ใช้โดยเคอร์เนล: ซึ่งก่อนหน้านี้ไดเรกทอรีเป็นรายการเชิงเส้นต่อมาระบบแฟ้มเริ่มใช้ hashtables, B-trees และอื่น ๆ ดังนั้นการอ่านไดเรกทอรีโดยตรงไม่ได้ตรงไปตรงมาอีกต่อไปแล้วเคอร์เนลจึงเพิ่มฟังก์ชั่นเฉพาะสำหรับสิ่งนี้ (ฉันไม่แน่ใจว่านั่นเป็นเหตุผลหลักหรือหากพวกเขาถูกเพิ่มเข้ามาด้วยเหตุผลอื่น ๆ เช่นการแคช)

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

ดังนั้น macOS อาจเป็นหนึ่งในระบบปฏิบัติการที่เคอร์เนลอนุญาตตราบเท่าที่ระบบไฟล์ให้ข้อมูล และความแตกต่างคือ/devอยู่ในdevfsระบบไฟล์ที่ถูกเขียนขึ้นเพื่ออนุญาตสิ่งนี้ในวันแรกขณะที่/อยู่ในระบบไฟล์ APFS ที่ละเว้นคุณสมบัตินี้โดยไม่จำเป็นในยุคปัจจุบัน

ข้อจำกัดความรับผิดชอบ: ฉันยังไม่ได้ทำการวิจัยใด ๆ เกี่ยวกับ BSD หรือ macOS ฉันแค่ปีกมัน


ดูเหมือนว่าจะสมเหตุสมผล มีส่วนอื่น ๆ ของหน่วยความจำที่แตกต่างจากระบบไฟล์ระบบปฏิบัติการมาตรฐานหรือไม่? ฉันคิดว่า/etcจะใช้ดังนั้นฉันจึงใช้มันเป็นเกณฑ์มาตรฐานของฉัน
haboutnnah

2
ในทางตรงกันข้ามโดยทั่วไป / etc เป็นเพียงโฟลเดอร์ปกติที่มีไฟล์ปกติ มีอาจจะเป็นระบบไฟล์เสมือนอื่น ๆ แม้ว่า - วิ่งmountหรือ/sbin/mountเพื่อดูสิ่งที่กำลังติดตั้งอยู่ที่
grawity

คุณถูก! ดูสิ่งนี้: i.imgur.com/pcVpo1o.png
haboutnnah

นี่คือ @grawity ที่ประณีตจริงๆ, i.imgur.com/8QuR0FK.png
haboutnnah

6
@haboutnnah ภาพหน้าจอของคุณยืนยันว่า/devเป็นระบบไฟล์เสมือนโดยใช้devfsไดรเวอร์โดย/etcเป็นส่วนหนึ่งของ/ระบบไฟล์โดยใช้apfsไดรเวอร์ ดังนั้นเหตุผลที่catจะอ่านข้อหนึ่งไม่ใช่เหตุผลอื่นคือความแตกต่างระหว่างapfsและdevfsไดรเวอร์
kasperd
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.