Katakanlah saya masuk ke shell pada sistem unix dan mulai mengetuk perintah. Saya awalnya mulai di direktori home pengguna saya ~
. Saya mungkin dari sana cd
ke direktori Documents
.
Perintah untuk mengubah direktori kerja di sini sangat sederhana secara intuitif untuk dipahami: simpul induk memiliki daftar simpul anak yang dapat diakses, dan mungkin ia menggunakan varian (yang dioptimalkan) dari pencarian untuk menemukan keberadaan simpul anak dengan beri nama pengguna yang dimasukkan, dan direktori kerja kemudian "diubah" untuk mencocokkan ini - koreksi saya jika saya salah di sana. Bahkan mungkin lebih sederhana bahwa shell cukup "naif" mencoba untuk mencoba mengakses direktori persis seperti yang diinginkan pengguna dan ketika sistem file mengembalikan beberapa jenis kesalahan, shell menampilkan respons yang sesuai.
Apa yang saya tertarik adalah bagaimana proses yang sama bekerja ketika saya menavigasi direktori, yaitu ke orang tua, atau orang tua orang tua.
Mengingat lokasi saya yang tidak diketahui, mungkin "buta" Documents
, salah satu dari banyak direktori di seluruh pohon sistem file dengan nama itu, bagaimana cara Unix menentukan di mana saya harus ditempatkan selanjutnya? Apakah itu merujuk pwd
dan memeriksanya? Jika ya, bagaimana pwd
melacak kondisi navigasi saat ini?
sumber
Jawaban:
Jawaban lainnya adalah penyederhanaan yang berlebihan, masing-masing hanya menyajikan sebagian dari cerita, dan salah dalam beberapa hal.
Ada dua cara direktori kerja dilacak:
chdir()
danfchdir()
panggilan sistem, yang terakhir olehchroot()
. Orang dapat melihatnya secara tidak langsung di/proc
sistem operasi Linux atau melaluifstat
perintah di FreeBSD dan sejenisnya:Ketika resolusi pathname beroperasi, itu dimulai pada satu atau yang lain dari vnodes yang dirujuk, sesuai dengan apakah path relatif atau absolut. (Ada keluarga
…at()
panggilan sistem yang memungkinkan resolusi pathname dimulai pada vnode yang dirujuk oleh deskriptor file open (direktori) sebagai opsi ketiga.)Dalam microkernel Unices, struktur datanya ada di ruang aplikasi, tetapi prinsip memegang referensi terbuka untuk direktori ini tetap sama.
chdir()
.Jika seseorang mengubah nama path relatif, ia memanipulasi string untuk menambahkan nama itu. Jika seseorang mengubah nama path absolut, itu menggantikan string dengan nama baru. Dalam kedua kasus, itu menyesuaikan string untuk menghapus
.
dan..
komponen dan untuk mengejar tautan simbolik menggantikannya dengan nama tertaut mereka. ( Berikut adalah kode shell Z untuk itu , misalnya.)Nama dalam variabel string internal dilacak oleh variabel shell bernama
PWD
(ataucwd
dalam shell C). Ini secara konvensional diekspor sebagai variabel lingkungan (bernamaPWD
) ke program yang dihasilkan oleh shell.Dua metode pelacakan hal ini diungkapkan oleh opsi
-P
dan-L
kecd
danpwd
perintah built-in shell, dan oleh perbedaan antarapwd
perintah built-in shell dan baik/bin/pwd
perintah dan perintah built-inpwd
dari hal-hal seperti (antara lain) VIM dan NeoVIM.Seperti yang Anda lihat: mendapatkan direktori kerja "logis" adalah masalah melihat
PWD
variabel shell (atau variabel lingkungan jika seseorang bukan program shell); sedangkan memperoleh direktori kerja "fisik" adalah masalah memanggilgetcwd()
fungsi perpustakaan.Pengoperasian
/bin/pwd
program ketika-L
opsi digunakan agak halus. Itu tidak bisa mempercayai nilaiPWD
variabel lingkungan yang telah diwarisi. Lagi pula, itu tidak perlu dipanggil oleh shell dan program intervensi mungkin tidak menerapkan mekanisme shell membuatPWD
variabel lingkungan selalu melacak nama direktori kerja. Atau seseorang dapat melakukan apa yang saya lakukan di sana.Jadi yang dilakukannya adalah (seperti standar POSIX mengatakan) memeriksa bahwa nama yang diberikan
PWD
menghasilkan hal yang sama dengan nama.
, seperti yang dapat dilihat dengan jejak panggilan sistem:Seperti yang Anda lihat: itu hanya memanggil
getcwd()
jika mendeteksi ketidakcocokan; dan itu bisa dibodohi dengan menetapkanPWD
ke string yang memang menamai direktori yang sama, tetapi dengan rute yang berbeda.Fungsi
getcwd()
perpustakaan adalah subjek dalam dirinya sendiri. Tetapi untuk précis:..
direktori. Itu berhenti ketika mencapai satu lingkaran di mana..
sama dengan direktori kerjanya atau ketika ada kesalahan mencoba untuk membuka berikutnya..
. Ini akan menjadi banyak panggilan sistem di bawah selimut.Namun, perhatikan bahwa bahkan pada FreeBSD dan sistem operasi lainnya, kernel tidak melacak direktori yang berfungsi dengan sebuah string.
Menavigasi ke
..
lagi adalah subjek dalam dirinya sendiri. Précis lain: Walaupun direktori secara konvensional (walaupun, seperti yang sudah disinggung, ini tidak diperlukan) mengandung aktual..
dalam struktur data direktori pada disk, kernel melacak direktori induk dari setiap direktori vnode itu sendiri dan dengan demikian dapat menavigasi ke..
vnode dari sembarang direktori kerja. Ini agak rumit oleh mountpoint dan mengubah mekanisme root, yang berada di luar cakupan jawaban ini.Ke samping
Windows NT sebenarnya melakukan hal serupa. Ada satu direktori kerja per proses, yang ditetapkan oleh
SetCurrentDirectory()
panggilan API dan dilacak per proses oleh kernel melalui sebuah pegangan file terbuka (internal) ke direktori itu; dan ada satu set variabel lingkungan yang digunakan oleh program Win32 (bukan hanya penerjemah perintah, tetapi semua program Win32) untuk melacak nama beberapa direktori kerja (satu per drive), menambahkan atau menimpa mereka setiap kali mereka mengubah direktori.Secara konvensional, tidak seperti halnya dengan sistem operasi Unix dan Linux, program Win32 tidak menampilkan variabel lingkungan ini kepada pengguna. Seseorang kadang-kadang dapat melihatnya dalam subsistem mirip Unix yang berjalan pada Windows NT, juga, dengan menggunakan perintah interpreter
SET
perintah dengan cara tertentu.Bacaan lebih lanjut
pwd
" . Open Group Base Spesifikasi Issue 7. IEEE 1003.1: 2008. Grup Terbuka. 2016sumber
..
dalam konteks Plan9,.
dan..
komponen dan untuk mengejar tautan simbolik menggantikannya dengan nama tertaut mereka. ... Nama dalam variabel string internal dilacak oleh variabel shell bernamaPWD
... "(penekanan ditambahkan). ... (Lanjutan)PWD
=…/b
setelahcd b
perintah, meskipunb
merupakan tautan simbolis kea
- jadi shell tidak “memburu”a -> b
tautan. Apakah Anda salah menyatakan, atau apakah saya salah membaca?CHASE_LINKS
,.Kernel tidak melacak direktori atau nama file; file atau direktori diwakili dalam kernel oleh pasangan inode / perangkat. Sistem panggilan seperti
chdir()
,open()
, dll mengambil jalan sebagai parameter, yang dapat absolut (misalnya/etc/passwd
), atau relatif ke direktori saat ini (contoh:Documents
,..
). Ketika proses dijalankanchdir("Documents")
, pencarian dilakukanDocuments
di dalam direktori kerja saat ini, dan direktori kerja proses diperbarui untuk merujuk ke direktori ini. Dari perspektif kernel, tidak ada yang istimewa dalam nama "..", itu hanya sebuah konvensi dalam sistem file yang..
merujuk ke direktori induk.The
getcwd()
fungsi bukan panggilan sistem, tetapi fungsi perpustakaan yang harus bekerja jalan sampai ke direktori root, merekam nama-nama komponen jalur di jalan.sumber
Menariknya, secara tradisional
cd ..
jauh lebih sederhana daripadapwd
. Direktori bernama..
ditempatkan secara eksplisit ke dalam sistem file. Sistem melacak perangkat / inode dari direktori saat ini, jadicd ..
atau lebih tepatnya panggilan sistemchdir("..")
hanya memerlukan mencari nama ".." dalam file milik inode direktori saat ini dan mengubah perangkat direktori saat ini / inode ke nilai ditemukan di sana.pwd
(lebih akurat/bin/pwd
) mengikuti..
tautan secara berturut-turut dan membaca direktori masing-masing hingga menemukan inode dari mana asalnya, menyusun daftar nama-nama itu secara terbalik hingga mencapai direktori root (terutama tidak mengandung..
entri).Sekarang ini adalah perilaku dasar tingkat rendah asli. Perintah shell yang sebenarnya
pwd
bukan mengandalkan berbagai teknik caching nama jalur saat ini. Tetapi pada intinya, hanya inode-nya saja yang benar-benar diketahui. Itu menyiratkan bahwa sekali symlink digunakan untuk menavigasi direktori, pengertian nama direktori kerja saat ini dari shell saat ini dan sistem/bin/pwd
mungkin berbeda.sumber