การทำความเข้าใจ / dev และตำบลและไฟล์ของมัน


51
$ ls -l /dev/stdin /dev/fd/0
lrwx------ 1 tim tim 64 2011-08-07 09:53 /dev/fd/0 -> /dev/pts/2
lrwxrwxrwx 1 root root 15 2011-08-06 08:14 /dev/stdin -> /proc/self/fd/0
$ ls -l /dev/pts/2 /proc/self/fd/0
crw--w---- 1 tim tty  136, 2 2011-08-07 09:54 /dev/pts/2
lrwx------ 1 tim tim     64 2011-08-07 09:54 /proc/self/fd/0 -> /dev/pts/2
  1. ฉันสงสัยว่าไฟล์ทั้งหมดที่อยู่ภายใต้/devและไดเรกทอรีย่อยนั้นเป็นตัวอธิบายไฟล์ทั้งหมดของอุปกรณ์หรือไม่
  2. ทำไมถึงมีลิงค์มากมายจากกัน? ตัวอย่างเช่น/dev/fd/0, /dev/stdin, มีการเชื่อมโยงทั้งหมดเพื่อ/proc/self/fd/0/dev/pts/2
  3. หากlในlrwx------การเชื่อมโยงหมายถึงสิ่งที่ไม่cอยู่ในcrw--w---- ความหมายว่าอย่างไร

3
และตอบ # 3, C ย่อมาจากอุปกรณ์ตัวหรืออักขระพิเศษ ขย่อมาจากบล็อกพิเศษ
felixphew

คำตอบ:


77

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

ไฟล์อุปกรณ์มีสองประเภท: อุปกรณ์บล็อก (ระบุโดยbเป็นอักขระตัวแรกในเอาต์พุตls -l) และอุปกรณ์อักขระ (ระบุโดยc) ความแตกต่างระหว่างอุปกรณ์บล็อกและตัวละครนั้นไม่เป็นสากลอย่างสมบูรณ์ อุปกรณ์บล็อกคือสิ่งต่าง ๆ เช่นดิสก์ซึ่งมีลักษณะเหมือนไฟล์ขนาดใหญ่ขนาดคงที่: หากคุณเขียนไบต์ที่ออฟเซ็ตและอ่านจากอุปกรณ์ที่ออฟเซ็ตนั้นคุณจะได้รับไบท์นั้นกลับมา อุปกรณ์ตัวละครเป็นอะไรก็ได้ที่การเขียนไบต์มีผลทันที (เช่นมันถูกปล่อยออกมาในสายอนุกรม) และการอ่านไบต์ก็มีผลทันที (เช่นการอ่านจากพอร์ตอนุกรม)

ความหมายของไฟล์อุปกรณ์ถูกกำหนดโดยหมายเลขไม่ใช่ชื่อ (ชื่อมีความสำคัญกับแอปพลิเคชัน แต่ไม่ใช่เคอร์เนล) จำนวนนั้นเป็นสองตัวเลขจริง ๆ : หมายเลขหลักระบุว่าไดรเวอร์ใดรับผิดชอบอุปกรณ์นี้และหมายเลขรองทำให้ผู้ขับขี่สามารถขับอุปกรณ์ได้หลายเครื่อง¹ หมายเลขเหล่านี้จะปรากฏในls -lรายการซึ่งโดยปกติคุณจะพบขนาดไฟล์ เช่นbrw-rw---- 1 root disk 8, 0 Jul 12 15:54 /dev/sda→อุปกรณ์นี้เป็นหลัก 8, รอง 0

ไฟล์อุปกรณ์ภายใต้บางไฟล์/devไม่ตรงกับอุปกรณ์ฮาร์ดแวร์ หนึ่งที่มีอยู่ในทุกระบบยูนิกซ์คือ/dev/null; การเขียนถึงมันไม่มีผลกระทบและการอ่านจากมันจะไม่ส่งคืนข้อมูลใด ๆ มักจะสะดวกในเชลล์สคริปต์เมื่อคุณต้องการละเว้นเอาต์พุตจากคำสั่ง ( >/dev/null) หรือรันคำสั่งที่ไม่มีอินพุต ( </dev/null) ตัวอย่างทั่วไปอื่น ๆ ที่มี/dev/zero(ซึ่งจะส่งกลับไบต์ null ไม่มีที่สิ้นสุด ) /dev/urandom(ซึ่งผลตอบแทนที่สุ่มไบต์ไม่มีที่สิ้นสุด )

ไฟล์อุปกรณ์บางไฟล์มีความหมายที่ขึ้นอยู่กับกระบวนการที่เข้าถึงได้ ตัวอย่างเช่น/dev/stdinกำหนดอินพุตมาตรฐานของกระบวนการปัจจุบัน การเปิดจากมีผลคล้ายกับการเปิดไฟล์ต้นฉบับที่เปิดเป็นอินพุตมาตรฐานของกระบวนการ ในทำนองเดียวกัน/dev/ttyกำหนดเทอร์มินัลที่เชื่อมต่อกระบวนการ ภายใต้ Linux ทุกวันนี้/dev/stdinและเพื่อน ๆ ไม่ได้ถูกนำมาใช้เป็นอุปกรณ์ตัวอักษร แต่เป็นการเชื่อมโยงสัญลักษณ์ไปยังกลไกทั่วไปที่อนุญาตให้อ้างอิงไฟล์ descriptor ทุกไฟล์ (แทนที่จะเป็นเพียง 0, 1 และ 2 ภายใต้วิธีดั้งเดิม); ตัวอย่างเช่นการเชื่อมโยงสัญลักษณ์/dev/stdin /proc/self/fd/0ดูที่/ dev / fd เกี่ยวข้องกับ / proc / self / fd / อย่างไร .

คุณจะพบลิงค์สัญลักษณ์/devมากมาย สิ่งนี้อาจเกิดขึ้นได้จากเหตุผลในอดีต: ไฟล์อุปกรณ์ถูกย้ายจากชื่อหนึ่งไปยังอีกชื่อหนึ่ง แต่บางแอปพลิเคชันยังคงใช้ชื่อเดิม ตัวอย่างเช่น/dev/scd0เป็นลิงค์สัญลักษณ์/dev/sr0ภายใต้ Linux; ทั้งกำหนดอุปกรณ์ซีดีเครื่องแรก เหตุผลสำหรับการเชื่อมโยงสัญลักษณ์อีกอย่างหนึ่งคือองค์กร: ภายใต้ Linux คุณจะพบฮาร์ดดิสก์ของคุณและพาร์ทิชันในหลายสถานที่: /dev/sdaและ/dev/sda1และเพื่อน (แต่ละดิสก์ที่กำหนดโดยตัวอักษรโดยพลการและพาร์ทิชันตามรูปแบบพาร์ทิชัน), /dev/disk/by-id/*(ดิสก์ที่กำหนดโดย หมายเลขซีเรียลที่ไม่ซ้ำกัน), /dev/disk/by-label/*(พาร์ติชันที่มีระบบไฟล์กำหนดโดยฉลากที่มนุษย์เลือก); และอื่น ๆ. ลิงก์สัญลักษณ์ยังใช้เมื่อชื่ออุปกรณ์ทั่วไปอาจเป็นหนึ่งในหลาย ๆ ตัวอย่างเช่น/dev/dvdอาจเป็นลิงก์สัญลักษณ์/dev/sr0หรืออาจเป็นลิงก์ไปยัง/dev/sr1หากคุณมีเครื่องอ่านซีดีสองเครื่องและเครื่องที่สองคือเครื่องอ่าน DVD เริ่มต้น

ท้ายที่สุดมีไฟล์อื่น ๆ อีกสองสามไฟล์ที่คุณอาจพบภายใต้/devเหตุผลดั้งเดิม คุณจะไม่พบสิ่งเดียวกันในทุกระบบ บน Unices ที่สุด/dev/logเป็นซ็อกเก็ตที่ใช้โปรแกรมในการปล่อยข้อความเข้าสู่ระบบ เป็นสคริปต์ที่สร้างรายการใน/dev/MAKEDEV /devบนระบบลินุกซ์ที่ทันสมัยในรายการ/dev/ที่ถูกสร้างขึ้นโดยอัตโนมัติudev , MAKEDEVobsoleting

¹สิ่งนี้ไม่เป็นความจริงภายใต้ Linux อีกต่อไป แต่รายละเอียดนี้มีความสำคัญต่อผู้เขียนโปรแกรมควบคุมอุปกรณ์เท่านั้น


ขอบคุณ! โดย "ความหมายของไฟล์อุปกรณ์นั้นพิจารณาจากหมายเลข" คุณหมายถึง file descriptor หรือไม่
ทิม

@Tim: ไม่ตัวเลขปรากฏในls -lรายการโดยปกติคุณจะพบขนาดไฟล์ก่อนวันที่เช่นbrw-rw---- 1 root disk 8, 0 Jul 12 15:54 /dev/sda→อุปกรณ์นี้เป็นหลัก 8, รอง 0 หมายเลขอุปกรณ์ไม่ได้เกิดขึ้นบ่อยในทางปฏิบัติฉันเพิ่งพูดถึงพวกเขาเพื่อพูด สิ่งที่ทำให้อุปกรณ์เป็นอุปกรณ์ (ที่สำคัญที่สุดไม่ใช่ชื่อไฟล์) หมายเลขตัวอธิบายไฟล์มีความหมายในกระบวนการเฉพาะเท่านั้น
Gilles 'หยุดชั่วร้าย'

ไม่การเปิด/dev/stdin(=> /proc/self/fd/0) บน Linux ไม่มีผลเหมือนกับการทำสำเนาอินพุตมาตรฐาน หากต้องการดูความแตกต่างsu - non_root_userจากนั้นexec 5</dev/stdinจะล้มเหลวด้วย "การอนุญาตที่ถูกปฏิเสธ" แต่exec 5<&0จะประสบความสำเร็จ และไม่เพียง แต่ fd ใหม่จะถูกเปิดด้วยแฟล็กที่แตกต่างกันทุกอย่างเกี่ยวกับอ็อบเจ็กต์ไฟล์ ("open file descrip tion " ใน POSIX lingo) จะแตกต่างกัน (ตัวชี้ไฟล์ออฟเซ็ต, โหมดไม่บล็อก / ฯลฯ )
mosvy

14
  1. ใช่ - ไม่ว่าโดยตรงหรือเป็นสัญลักษณ์ - นั่นคือสิ่งที่/dev/มีไว้สำหรับ
  2. เพื่อวัตถุประสงค์ต่างๆ: บางครั้งการทำงานร่วมกันระหว่างการตั้งชื่อรูปแบบบางครั้งก็เป็นสิ่งจำเป็นสำหรับสภาพแวดล้อมการทำงาน - /dev/stdinในขณะที่ตัวอย่างของ นี่ไม่ได้ชี้ไปที่แบบคงที่/dev/pts/2หรืออื่น ๆ - เพียงแค่เปลี่ยนไปที่เทอร์มินัลอื่นแล้วคุณจะเห็น /dev/stdinเป็นอินพุตมาตรฐานของเซสชันเทอร์มินัลปัจจุบันของคุณ นี่เป็นตัวอย่างว่าทำไมจึงต้องมี symlink
  3. ดูและman mknod info coreutils 'mknod invocation'โดยทั่วไปcย่อมาจากประเภทอุปกรณ์อักขระ

3
"อินพุตมาตรฐานของเซสชันเทอร์มินัลปัจจุบันของคุณ" ค่อนข้างคลุมเครือ /dev/stdinอ้างถึงอินพุตมาตรฐานของกระบวนการที่จะเปิด ทุกอย่างใน/proc/$pidนั้นเป็นข้อมูลที่ขึ้นอยู่กับกระบวนการและ/proc/selfเป็น symlink เวทมนต์ที่ชี้ไปยังข้อมูลของกระบวนการ
Stéphane Gimenez

11

สำหรับคำถามแรกของคุณไม่ใช่ตัวอธิบายไฟล์ แต่เป็นไฟล์อุปกรณ์ (aka "โหนด dev")

ไฟล์เหล่านั้นถูกผูกไว้กับไดรเวอร์ที่ใช้จัดการอุปกรณ์โดยใช้หมายเลขหลักและรอง (ตัวอย่างเช่น "136, 2" ในlsเอาต์พุตของคุณอ้างถึงไดรเวอร์อุปกรณ์ที่เชื่อมโยงกับหมายเลขหลัก 136 และระบุอุปกรณ์ # 2 ที่จัดการโดยไดรเวอร์นั้น)

ตัวอักษรแรกของการส่งออกls -lเป็นประเภทของอุปกรณ์ในกรณีของไฟล์อุปกรณ์ ถ้ามันเป็น 'c' มันเป็นอุปกรณ์ตัวละครหรือถ้ามันเป็น 'b' มันเป็นอุปกรณ์บล็อก

สำหรับคำถามที่สองของคุณอ้างอิงคำตอบข้างต้นโดย rozcietrzewiacz


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