Saya bisa cat /dev
, saya bisa ls /dev
, saya tidak bisa less /dev
. Mengapa cat
saya membiarkan cat
direktori ini tetapi tidak ada direktori lain?
Saya bisa cat /dev
, saya bisa ls /dev
, saya tidak bisa less /dev
. Mengapa cat
saya membiarkan cat
direktori ini tetapi tidak ada direktori lain?
Jawaban:
Secara historis (hingga V7 UNIX, atau sekitar 1979) read
pemanggilan sistem bekerja pada file dan direktori. read
pada direktori akan mengembalikan struktur data sederhana yang akan diuraikan oleh program pengguna untuk mendapatkan entri direktori. Memang, ls
alat V7 melakukan hal ini - read
pada direktori, parsing struktur data yang dihasilkan, output dalam format daftar terstruktur.
Ketika filesystem menjadi lebih kompleks, struktur data "sederhana" ini menjadi lebih rumit, ke titik di mana readdir
fungsi perpustakaan ditambahkan untuk membantu program mem-parsing output read(directory)
. Sistem dan sistem file yang berbeda mungkin memiliki format pada disk yang berbeda, yang semakin rumit.
Ketika Sun memperkenalkan Network File System (NFS), mereka ingin sepenuhnya menghilangkan struktur direktori on-disk. Alih-alih membuat mereka read(directory)
menjadi representasi platform-independen dari direktori, namun, mereka menambahkan panggilan sistem baru - getdirents
- dan dilarang read
pada direktori yang dipasang di jaringan. Panggilan sistem ini dengan cepat diadaptasi untuk bekerja pada semua direktori dalam berbagai rasa UNIX, menjadikannya cara standar untuk mendapatkan isi direktori. (Sejarah disarikan dari https://utcc.utoronto.ca/~cks/space/blog/unix/ReaddirHistory )
Karena readdir
sekarang merupakan cara standar untuk membaca direktori, read(directory)
biasanya tidak diimplementasikan (kembali -EISDIR) pada kebanyakan OS modern (QNX, misalnya, adalah pengecualian yang diterapkan readdir
sebagai read(directory)
). Namun, dengan desain "sistem file virtual" di sebagian besar kernel modern, sebenarnya tergantung pada sistem file individual apakah membaca direktori berfungsi atau tidak.
Dan memang, pada macOS, sistem devfs
file yang mendasari /dev
mountpoint benar-benar mendukung pembacaan ( https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/bsd/miscfs/devfs/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);
Ini secara eksplisit memanggil READDIR
jika Anda mencoba membaca /dev
(membaca file di bawah /dev
ditangani oleh fungsi terpisah - devfsspec_read
). Jadi, jika suatu program memanggil read
sistem panggilan aktif /dev
, itu akan berhasil dan mendapatkan daftar direktori!
Ini adalah fitur yang efektif yang merupakan peninggalan dari hari-hari awal UNIX, dan yang belum tersentuh dalam waktu yang sangat lama. Sebagian dari saya curiga bahwa ini sedang disimpan karena alasan kompatibilitas ke belakang, tetapi bisa dengan mudah menjadi kenyataan bahwa tidak ada yang cukup peduli untuk menghapus fitur karena tidak benar-benar menyakiti apa pun.
Less adalah penampil file teks, cat adalah alat untuk menyalin data sewenang-wenang. Jadi, kurang melakukan pemeriksaan sendiri untuk memastikan Anda tidak membuka sesuatu yang akan memiliki data dalam jumlah besar atau berperilaku sangat aneh. Di sisi lain, cat tidak memiliki pemeriksaan seperti itu sama sekali - jika kernel memungkinkan Anda membuka sesuatu (bahkan jika itu pipa atau perangkat atau sesuatu yang lebih buruk), cat akan membacanya.
Jadi mengapa OS memungkinkan kucing untuk membuka direktori? Secara tradisional dalam sistem BSD-style, semua direktori dapat dibaca sebagai file, dan begitulah program akan membuat daftar direktori di tempat pertama: dengan hanya menafsirkan struktur dirent yang tersimpan pada disk.
Kemudian, struktur-struktur pada disk mulai menyimpang dari direktori yang digunakan oleh kernel: di mana sebelumnya direktori adalah daftar linear, sistem file kemudian mulai menggunakan hashtable, B-tree, dan sebagainya. Jadi membaca direktori secara langsung tidak mudah lagi - kernel mengembangkan fungsi khusus untuk ini. (Saya tidak yakin apakah itu alasan utama, atau apakah mereka terutama ditambahkan karena alasan lain seperti caching.)
Beberapa sistem BSD terus membiarkan Anda membuka semua direktori untuk dibaca; Saya tidak tahu apakah mereka memberi Anda data mentah dari disk, atau apakah mereka mengembalikan daftar direktori yang ditiru, atau apakah mereka membiarkan driver sistem file memutuskan.
Jadi mungkin macOS adalah salah satu dari sistem operasi di mana kernel memungkinkannya selama sistem file menyediakan data. Dan perbedaannya adalah /dev
pada devfs
sistem file yang ditulis untuk memungkinkan hal ini pada hari-hari awal, sementara /
pada sistem file APFS yang menghilangkan fitur ini sebagai tidak perlu di zaman modern.
Penafian: Saya belum benar-benar melakukan penelitian tentang BSD atau macOS. Saya hanya mengayunkannya.
/etc
akan, jadi saya menggunakan itu sebagai tolok ukur saya.
mount
atau /sbin/mount
untuk melihat apa yang sedang dipasang di mana.
/dev
adalah sistem file virtual menggunakan devfs
driver sedangkan itu /etc
adalah bagian dari /
sistem file menggunakan apfs
driver. Jadi alasannya cat
akan membaca satu dan bukan yang lain adalah perbedaan antara apfs
dan devfs
driver.
neofetch
informasi Anda :) i.imgur.com/3azpnDt.png