Jawaban lainnya adalah penyederhanaan yang berlebihan, masing-masing hanya menyajikan sebagian dari cerita, dan salah dalam beberapa hal.
Ada dua cara direktori kerja dilacak:
- Untuk setiap proses, dalam struktur data ruang-kernel yang mewakili proses itu, kernel menyimpan dua referensi vnode ke vnodes direktori kerja dan direktori root untuk proses itu. Referensi sebelumnya diatur oleh
chdir()
dan fchdir()
panggilan sistem, yang terakhir oleh chroot()
. Orang dapat melihatnya secara tidak langsung di /proc
sistem operasi Linux atau melalui fstat
perintah di FreeBSD dan sejenisnya:% fstat -p $$ | head -n 5
MODE PENGGUNA CMD PID FD MOUNT INUM SZ | DV R / W
JdeBP zsh 92648 teks / 24958 -r-xr-xr-x 702360 r
JdeBP zsh 92648 ctty / dev 148 crw - w ---- pts / 4 rw
JdeBP zsh 92648 wd / usr / home / JdeBP 4 drwxr-xr-x 124 r
JdeBP zsh 92648 root / 4 drwxr-xr-x 35 r
%
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.
- Secara internal, di dalam shell seperti Z, Korn, Bourne Again, C, dan shell Almquist, shell juga melacak direktori kerja menggunakan manipulasi string dari variabel string internal. Ini melakukan ini setiap kali ada alasan untuk menelepon
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
(atau cwd
dalam shell C). Ini secara konvensional diekspor sebagai variabel lingkungan (bernama PWD
) ke program yang dihasilkan oleh shell.
Dua metode pelacakan hal ini diungkapkan oleh opsi -P
dan -L
ke cd
dan pwd
perintah built-in shell, dan oleh perbedaan antara pwd
perintah built-in shell dan baik /bin/pwd
perintah dan perintah built-in pwd
dari hal-hal seperti (antara lain) VIM dan NeoVIM.
% mkdir a; ln -sab
% (cd b; pwd; / bin / pwd; printenv PWD)
/ usr / home / JdeBP / b
/ usr / home / JdeBP / a
/ usr / home / JdeBP / b
% (cd b; pwd -P; / bin / pwd -P)
/ usr / home / JdeBP / a
/ usr / home / JdeBP / a
% (cd b; pwd -L; / bin / pwd -L)
/ usr / home / JdeBP / b
/ usr / home / JdeBP / b
% (cd -P b; pwd; / bin / pwd; printenv PWD)
/ usr / home / JdeBP / a
/ usr / home / JdeBP / a
/ usr / home / JdeBP / a
% (cd b; PWD = / hello / there / bin / pwd -L)
/ usr / home / JdeBP / a
%
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 memanggil getcwd()
fungsi perpustakaan.
Pengoperasian /bin/pwd
program ketika -L
opsi digunakan agak halus. Itu tidak bisa mempercayai nilai PWD
variabel lingkungan yang telah diwarisi. Lagi pula, itu tidak perlu dipanggil oleh shell dan program intervensi mungkin tidak menerapkan mekanisme shell membuat PWD
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:
% ln -sac
% (cd b; truss / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ("/ usr / home / JdeBP / b", { mode = drwxr-xr-x, inode = 120932, size = 2, blksize = 131072}) = 0 (0x0)
stat (".", {mode = drwxr-xr-x, inode = 120932, size = 2, blksize = 131072}) = 0 (0x0)
/ usr / home / JdeBP / b
% (cd b; PWD = / usr / local / etc truss / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ("/ usr / local / etc" , {mode = drwxr-xr-x, inode = 14835, size = 158, blksize = 10240}) = 0 (0x0)
stat (".", {mode = drwxr-xr-x, inode = 120932, size = 2 , blksize = 131072}) = 0 (0x0)
__getcwd ("/ usr / home / JdeBP / a", 1024) = 0 (0x0)
/ usr / home / JdeBP / a
% (cd b; PWD = / halo / ada truss / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ("/ hello / there", 0x7fffffffe730) ERR # 2 'Tidak ada file atau direktori'
__getcwd ("/ usr / home / JdeBP / a", 1024) = 0 (0x0)
/ usr / home / JdeBP / a
% (cd b; PWD = / usr / home / JdeBP / c truss / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ("/ usr / home / JdeBP / c ", {mode = drwxr-xr-x, inode = 120932, size = 2, blksize = 131072}) = 0 (0x0)
stat (". ", {Mode = drwxr-xr-x, inode = 120932 , size = 2, blksize = 131072}) = 0 (0x0)
/ usr / home / JdeBP / c
%
Seperti yang Anda lihat: itu hanya memanggil getcwd()
jika mendeteksi ketidakcocokan; dan itu bisa dibodohi dengan menetapkan PWD
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:
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