Ada file khusus di Linux yang sebenarnya bukan file.
Contoh-contoh yang paling terkenal dan jelas ini ada di dev
folder, "file" seperti:
/dev/null
- Abaikan apa pun yang Anda tulis ke file/dev/random
- Output data acak, bukan isi file/dev/tcp
- Mengirim semua data yang Anda tulis ke file ini melalui jaringan
Pertama-tama, apa nama dari jenis-jenis "file" yang benar-benar semacam skrip atau biner yang menyamar?
Kedua, bagaimana mereka diciptakan? Apakah file-file ini dibangun ke dalam sistem pada level kernel, atau adakah cara untuk membuat "file ajaib" sendiri (bagaimana dengan a /dev/rickroll
)?
man 2 mknod
open()
,read()
,close()
, dll Setelah itu, terserah softwareJawaban:
/dev/zero
adalah contoh "file khusus" - khususnya, "simpul perangkat". Biasanya ini bisa diciptakan oleh proses instalasi distro, tetapi Anda dapat benar-benar membuatnya sendiri jika Anda ingin.Jika Anda bertanya
ls
tentang/dev/zero
:"C" di awal memberitahu Anda bahwa ini adalah "perangkat karakter"; tipe lainnya adalah "block device" (dicetak
ls
sebagai "b"). Secara kasar, perangkat akses acak seperti harddisk cenderung menjadi perangkat blok, sementara hal-hal berurutan seperti tape drive atau kartu suara Anda cenderung menjadi perangkat karakter.Bagian "1, 5" adalah "nomor perangkat utama" dan "nomor perangkat minor".
Dengan informasi ini, kita dapat menggunakan
mknod
perintah untuk membuat simpul perangkat kita sendiri:Ini membuat file baru bernama
foobar
, di folder saat ini, yang melakukan hal yang persis sama/dev/zero
. (Tentu saja Anda dapat mengatur izin yang berbeda di atasnya jika Anda mau.) Semua "file" ini benar-benar berisi adalah tiga item di atas - jenis perangkat, nomor utama, nomor kecil. Anda dapat menggunakanls
untuk mencari kode untuk perangkat lain dan membuat ulang juga. Ketika Anda bosan, cukup gunakanrm
untuk menghapus node perangkat yang baru saja Anda buat.Pada dasarnya nomor utama memberitahu kernel Linux yang driver perangkat untuk berbicara, dan nomor kecil memberitahu driver perangkat yang Anda bicarakan. (Misalnya, Anda mungkin memiliki satu pengontrol SATA, tetapi mungkin beberapa harddisk terhubung ke dalamnya.)
Jika Anda ingin menemukan perangkat baru yang melakukan sesuatu yang baru ... yah, Anda perlu mengedit kode sumber untuk kernel Linux dan mengkompilasi kernel kustom Anda sendiri. Jadi jangan lakukan itu! :-) Tetapi Anda dapat menambahkan file perangkat yang menduplikasi yang sudah Anda miliki dengan baik. Sistem otomatis seperti udev pada dasarnya hanya mengawasi acara perangkat dan memanggil
mknod
/rm
untuk Anda secara otomatis. Tidak ada yang lebih ajaib dari itu.Masih ada lainnya jenis file khusus:
Linux menganggap direktori sebagai jenis file khusus. (Biasanya Anda tidak bisa langsung membuka direktori, tetapi jika Anda bisa, Anda akan menemukan itu adalah file normal yang berisi data dalam format khusus, dan memberi tahu kernel tempat menemukan semua file dalam direktori itu.)
Symlink adalah file khusus. (Tapi tautan keras tidak.) Anda dapat membuat symlink menggunakan
ln -s
perintah. (Carilah halaman manual untuk itu.)Ada juga hal yang disebut "pipa bernama" atau "FIFO" (antrian masuk pertama, keluar pertama). Anda dapat membuatnya dengan
mkfifo
. FIFO adalah file ajaib yang dapat dibuka oleh dua program sekaligus - satu membaca, satu tulisan. Ketika ini terjadi, ia bekerja seperti pipa shell normal. Tetapi Anda dapat memulai setiap program secara terpisah ...File yang tidak "spesial" dengan cara apa pun disebut "file biasa". Anda kadang-kadang akan melihat menyebutkan ini di dokumentasi Unix. Itu artinya; file yang bukan node perangkat atau symlink atau apa pun. Hanya file biasa, setiap hari tanpa properti magis.
sumber
mknod
, jalankancat /proc/devices
untuk melihat nomor utama untuk semua driver. Yang membawa kita ke jenis file khusus/proc
sistem file lainnya ( jawaban ini membicarakannya).Sebagian besar
/dev
entri adalah blok perangkat inode atau karakter perangkat inode. Wikipedia memiliki banyak detail tentang itu, yang tidak akan saya ulangi.Tetapi
/dev/tcp
yang disebutkan dalam pertanyaan Anda tidak dijelaskan oleh jawaban yang ada./dev/tcp
dan/dev/udp
berbeda dari kebanyakan/dev
entri lainnya . Perangkat blok dan karakter diimplementasikan oleh kernel, tetapi/dev/tcp
dan/dev/udp
diimplementasikan dalam mode pengguna.Bash shell adalah salah satu program yang memiliki implementasi
/dev/tcp
dan/dev/udp
(disalin dariksh93
). Ketika Anda mencoba untuk membuka jalur di bawah mereka yang memiliki operator pengalihan bash, itu tidak akan melakukanopen
panggilan sistem biasa . Sebaliknya bash akan membuat soket TCP dan menghubungkannya ke port yang ditentukan.Itu diimplementasikan dalam mode pengguna dan hanya dalam beberapa program seperti yang dapat dilihat pada contoh berikut yang menunjukkan perbedaan antara membiarkan
bash
dancat
mencoba membuka/dev/tcp/::1/22
Perbedaannya
ksh93
adalah bahwabash
hanya akan melakukan koneksi TCP dengan operator pengalihan, tidak di tempat lain di mana ia dapat membuka file sepertisource
atau.
builtin.sumber
gawk
memiliki kasus khusus yang sama/inet{,4,6}/{tcp,udp}/$port/$remote/$rport
, sejak sekitar 2010 (saya tidak ingat persis dan tidak dapat menemukan catatan rilis)./dev/tcp
adalah BUKAN file. Tidak pernah ada file bernama ini. Sintaks Bash untuk membuka soket menggunakan string/dev/tcp/address
seperti nama file, tetapi menyebutnya "file yang diimplementasikan di ruang pengguna" hanya terdengar aneh. Menarik yangksh
mengaitkan nama file itu untuk semuanya, bukan hanya pengalihan. Itu lebih dekat ke "menerapkan file".bash
hanya menyalin perilaku ini, tetapi itu berasal dari tempat lain.Selain node perangkat yang dijelaskan dalam jawaban lain (dibuat dengan mknod (2) atau disediakan oleh beberapa devfs ), Linux memiliki file "ajaib" lainnya yang disediakan oleh sistem file virtual khusus , khususnya di
/proc/
(lihat proc (5) , baca tentang procfs) ) dan dalam/sys/
(baca tentang sysfs ).File pseudo ini (yang muncul -eg to stat (2) - sebagai file biasa, bukan sebagai perangkat) adalah tampilan virtual yang disediakan oleh kernel; khususnya, membaca dari
/proc/
(misalnya dengancat /proc/$$/maps
, atau dengan membuka (2) -ing/proc/self/status
dalam program Anda) umumnya tidak melibatkan I / O fisik dari disk atau jaringan, jadi cukup cepat.Untuk membuat beberapa file pseudo tambahan pada
/proc/
umumnya Anda harus menulis modul kernel Anda sendiri dan memuatnya (lihat misalnya ini ).sumber
Mereka disebut node perangkat, dan dibuat secara manual dengan
mknod
atau secara otomatis olehudev
. Mereka biasanya berupa antarmuka seperti file ke perangkat karakter atau blokir dengan driver di kernel - mis. Disk adalah perangkat blok, ttys dan port serial dll. Adalah perangkat karakter.Ada jenis file "khusus" lainnya juga, termasuk pipa dan fifos dan soket bernama.
sumber
Karena pengguna lain telah menjelaskan dengan sangat rinci, file-file khusus memerlukan kode untuk mendukungnya. Namun, tampaknya tidak ada yang menyebutkan bahwa Linux menyediakan beberapa cara untuk menulis kode itu di userspace:
A. FUSE (Filesystem di USErspace) memungkinkan Anda untuk menulis sesuatu seperti
/proc
tanpa risiko menabrak kernel dan melakukannya dalam bahasa / runtime pilihan Anda, seperti Go , Node.js , Perl , PHP , Python , Ruby , Rust , dll .Ini juga memiliki keuntungan bahwa sistem file FUSE dapat dipasang tanpa
sudo
karena mereka berjalan sebagai pengguna melakukan pemasangan.Berikut adalah beberapa contoh hal-hal yang ditulis orang menggunakan FUSE:
B. Jika Anda ingin membuat perangkat input virtual seperti keyboard, mouse, joystick, dll. (Mis. Untuk menulis driver userspace untuk perangkat USB yang Anda gunakan
libusb
), ada uinput .Bindings untuk itu lebih sulit ditemukan, tetapi saya tahu mereka ada untuk Go (khusus Keyboard), Python , dan Ruby (2) .
Contoh penggunaan uinput dunia nyata meliputi:
C. Untuk perangkat karakter umum, ada CUSE (Perangkat karakter di USErspace). Ini jauh kurang populer.
Satu-satunya pengguna dari Cuse API bahwa aku secara pribadi sadar adalah program yang sama yang mendorong penciptaan: osspd , yang mengimplementasikan
/dev/dsp
,/dev/adsp
dan/dev/mixer
(API audio yang OSS) di userspace sehingga mereka dapat dialihkan melalui PulseAudio atau DMIX.Satu-satunya CUSE binding yang dapat saya temukan adalah cusepy , yang belum diperbarui sejak 2010.
D. Anda mungkin tidak memerlukan file khusus baru sama sekali.
Sebagai contoh, Anda dapat membuka komunikasi mentah dengan perangkat USB apa pun menggunakan libusb (Daftar binding pada halaman) dan kemudian berkomunikasi dengan program lain melalui beberapa mekanisme lain (soket TCP / UDP, membaca / menulis stdin / stdout atau file biasa pada disk , dll.).
sumber
poll
, tetapi karena cusepy menggunakan ctypes dan binding diautogasi berdasarkan file header C, memperbaiki setiap fungsi yang hilang hanyalah masalah menambahkan nama fungsi yang diinginkan ke daftar fungsi yang diekspor disetup.py
.Buku Linux Device Drivers (sangat disarankan) menjelaskan ini secara terperinci, dan bahkan telah Anda membuat modul kernel yang melakukan ini sebagai contoh, tetapi singkatnya, setiap driver perangkat memiliki fungsi spesifik yang dipanggil ketika file dibuka, ditutup , baca, tulis, dll. File "khusus" hanya melakukan sesuatu yang istimewa di dalam fungsi-fungsi itu, alih-alih mengakses perangkat keras penyimpanan pada disk.
Misalnya, fungsi tulis untuk
/dev/null
hanya tidak melakukan apa-apa, mengabaikan byte. Fungsi baca untuk/dev/random
mengembalikan nomor acak.sumber
mount -t devtmpfs
Sangat menarik untuk melihat bahwa dalam sistem modern,
/dev
biasanya tipe sistem file yang dapat dipasang di mana pun Anda inginkan. Ubuntu 16.04:Ini diaktifkan oleh
CONFIG_DEVTMPFS=y
, dan memungkinkan kernel itu sendiri untuk membuat dan menghancurkan file perangkat sesuai kebutuhan.CONFIG_DEVTMPFS_MOUNT=y
Opsi ini membuat kernel auto-mount devtmpfs aktif
/dev
.drivers/base/Kconfig
dokumen:file_operations
Terakhir, Anda harus membuat modul kernel perangkat karakter Anda sendiri untuk melihat apa yang sebenarnya terjadi.
Berikut adalah contoh runnable minimal: Memahami file perangkat karakter (atau karakter khusus)
Langkah paling penting, adalah menyiapkan
file_operations
struct, misalnya:yang berisi pointer fungsi yang dipanggil untuk setiap panggilan sistem terkait file.
Kemudian menjadi jelas bahwa Anda mengabaikan panggilan sistem terkait file tersebut untuk melakukan apa pun yang Anda inginkan, jadi beginilah cara kernel mengimplementasikan perangkat
/dev/zero
.Buat
/dev
entri di secara otomatis tanpamknod
Misteri terakhir adalah bagaimana kernel secara otomatis membuat
/dev
entri.Mekanisme ini dapat diamati dengan membuat modul kernel yang melakukan itu sendiri seperti yang ditunjukkan di: https://stackoverflow.com/questions/5970595/how-to-create-a-device-node-from-the-init-module- code-of-a-linux-kernel-module / 45531867 # 45531867 dan turun ke
device_create
panggilan.sumber