
Linux 中有一些特殊文件,但它們並不是真正的文件。
其中最顯著和最清晰的範例位於dev
資料夾「文件」中,例如:
/dev/null
- 忽略您寫入文件的任何內容/dev/random
- 輸出隨機資料而不是文件內容/dev/tcp
- 透過網路傳送您寫入此文件的任何數據
首先,這些類型的「檔案」的名稱是什麼,它們實際上是某種偽裝的腳本或二進位檔案?
其次,它們是如何創建的?這些檔案是在核心層級內建到系統中的,還是有辦法自己建立一個「魔術檔案」(怎麼樣/dev/rickroll
)?
答案1
/dev/zero
是「特殊檔案」的一個範例——特別是「設備節點」。通常這些是由發行版安裝過程創建的,但您可以完全如果您願意,可以自己創建它們。
如果您ls
詢問/dev/zero
:
# ls -l /dev/zero
crw-rw-rw- 1 root root 1, 5 Nov 5 09:34 /dev/zero
開頭的「c」告訴你這是一個「字元設備」;另一種類型是“區塊設備”(列印為ls
“b”)。粗略地說,像硬碟這樣的隨機存取設備往往是塊設備,而像磁帶驅動器或聲卡這樣的順序設備往往是字元設備。
「1、5」部分是「主設備號」和「次設備號」。
有了這些訊息,我們就可以使用mknod
命令來製作我們自己的設備節點:
# mknod foobar c 1 5
foobar
這會在當前資料夾中建立一個名為 , 的新文件,該文件的作用是確切地與 相同的事/dev/zero
。 (當然,如果你願意的話,你可以對其設定不同的權限。)這個「檔案」真正包含的就是上面的三項——裝置類型、主設備號、次設備號。您可以用來ls
尋找其他裝置的程式碼並重新建立這些程式碼。當你感到無聊時,只需使用rm
刪除剛剛創建的設備節點即可。
基本上,主裝置號碼告訴 Linux 核心要與哪個裝置驅動程式通信,次裝置號碼告訴裝置驅動程式您正在談論哪個裝置。 (例如,您可能有一個 SATA 控制器,但可能插入了多個硬碟。)
如果你想發明做新事情的新設備...好吧,您需要編輯 Linux 核心的原始程式碼並編譯您自己的自訂核心。所以我們不要這樣做! :-) 但是您可以新增與您已有的裝置檔案重複的裝置檔案。像 udev 這樣的自動化系統基本上只是監視裝置事件並自動為您呼叫mknod
/ 。rm
沒有什麼比這更神奇的了。
仍然有其他特殊文件種類:
Linux 認為目錄是一種特殊的檔案。 (通常你不能直接打開一個目錄,但如果可以的話,你會發現它是一個普通文件,包含特殊格式的數據,並告訴內核在哪裡可以找到該目錄中的所有文件。)
符號連結是一個特殊的文件。 (但硬連結不是。)您可以使用該
ln -s
命令建立符號連結。 (尋找它的線上說明頁。)還有一種稱為“命名管道”或“FIFO”(先進先出佇列)的東西。您可以使用 來建立一個
mkfifo
。 FIFO 是一個神奇的文件,可以透過以下方式打開二一次程式設計——一次閱讀,一次寫作。當這種情況發生時,它的工作方式就像普通的外殼管道一樣。但你可以單獨啟動每個程式......
無論如何都不“特殊”的文件稱為“常規文件”。您偶爾會在 Unix 文件中看到對此的提及。這就是它的意思;不是設備節點或符號連結或其他任何內容的檔案。只是一個普通的日常文件,沒有任何神奇的屬性。
答案2
大多數/dev
條目是區塊裝置 inode 或字元裝置 inode。維基百科有很多細節關於這一點,我不再重複。
但是/dev/tcp
您的問題中提到的任何現有答案都沒有解釋。/dev/tcp
並且/dev/udp
與大多數其他條目不同/dev
。塊設備和字元設備是由核心實現的,而/dev/tcp
和/dev/udp
是在用戶模式下實現的。
/dev/tcp
bash shell 是一個有和實作的程式/dev/udp
(複製自ksh93
)。當您嘗試使用 bash 重定向運算子開啟路徑時,它將不會執行普通的open
系統呼叫。相反,bash 將創建一個 TCP 套接字並將其連接到指定的連接埠。
這是在使用者模式下實現的,並且僅在某些程式中實現,如以下範例所示,該範例演示了 letbash
和cat
try to open之間的區別/dev/tcp/::1/22
$ cat /dev/tcp/::1/22
cat: /dev/tcp/::1/22: No such file or directory
$ cat < /dev/tcp/::1/22
SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.3
不同之處在於ksh93
,它bash
只會使用重定向運算子進行 TCP 連接,而不會在其他可能開啟檔案(如source
或.
內建)的地方進行。
答案3
答案4
正如其他用戶已經詳細解釋的那樣,特殊文件需要程式碼來備份它們。然而,似乎沒有人提到 Linux 提供了幾種在使用者空間編寫程式碼的方法:
A。 保險絲(USERspace 中的檔案系統)允許您編寫類似的內容,/proc
而不會導致核心崩潰,並以您選擇的語言/運行時來完成,例如去,Node.js,珀爾,PHP,Python, 紅寶石,鏽,ETC。。
它還具有無需安裝 FUSE 檔案系統的優點,sudo
因為它們以用戶執行安裝的方式運行。
以下是人們使用 FUSE 編寫的一些範例:
- mp3fs(將您的 FLAC 文件檢視為 MP3 文件,當您將它們複製/點擊並拖曳到 MP3 播放器時,這些檔案會即時建立)
- PyTagsFS(在根據元資料標籤建立的虛擬資料夾樹中查看您的媒體)
- 保險絲拉鍊(將 Zip 檔案安裝為資料夾)
- 保險絲ISO(無需root權限即可掛載ISO)
- 保險絲(安裝 i 設備)
- 熔斷器DAV(掛載WebDAV共享)
- 保險絲-exfat(掛載 exFAT 格式的檔案系統)
- NTFS-3G(這Linux NTFS 驅動程式)
B.如果你想建立一個虛擬輸入設備,例如鍵盤、滑鼠、操縱桿等(例如,為你正在使用的 USB 設備編寫使用者空間驅動程式libusb
),可以使用輸入法。
它的綁定很難找到,但我知道它們存在的目的去(僅限鍵盤),Python, 和紅寶石 (2)。
現實世界中 uinput 使用的範例包括:
- G15守護程式(Logitech G15 遊戲鍵盤上的 LCD 和遊戲按鍵的 Linux 驅動程式)
- ds4drv(Sony DualShock 4 控制器的驅動程式)
- xbox驅動(替代 Xbox 360 控制器驅動程式和 Linux 相當於x360ce設計得很糟糕的遊戲,例如亞軍2:未來節奏異形傳奇可以認為他們正在與真正的 Xbox 控制器對話,但實際上並非如此)
- Wiimote 老駕駛喜歡西維德在有人最終編寫核心 Wiimote 驅動程式之前需要這樣做,因此預設會提供支援。
C。對於通用字元設備,有庫塞(USERspace 中的字元設備)。但它不太受歡迎。
據我個人所知,CUSE API 的唯一使用者是促使其創建的相同程式:奧斯普德,它在用戶空間中實現/dev/dsp
、/dev/adsp
和/dev/mixer
(OSS 音訊 API),以便它們可以透過 PulseAudio 或 dmix 進行路由。
我能找到的唯一 CUSE 綁定是庫塞皮,自 2010 年以來就沒有更新過。
D .您可能根本不需要新的特殊文件。
例如,您可以使用以下命令開啟與任何 USB 裝置的原始通信libusb(頁面上的綁定清單),然後透過其他一些機制(TCP/UDP 套接字、讀取/寫入 stdin/stdout 或磁碟上的常規檔案等)與其他程式進行通訊。