GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana Unix Melacak Direktori Kerja Pengguna Saat Menavigasi Sistem File?

Katakanlah saya masuk ke shell pada sistem unix dan mulai mengetuk perintah. Saya awalnya memulai di direktori home pengguna saya ~ . Saya mungkin dari sana cd turun ke direktori Documents .

Perintah untuk mengubah direktori kerja di sini sangat sederhana secara intuitif untuk dipahami:simpul induk memiliki daftar simpul anak yang dapat diaksesnya, dan mungkin ia menggunakan varian pencarian (yang dioptimalkan) untuk menemukan keberadaan simpul anak dengan beri nama yang dimasukkan pengguna, dan direktori kerja kemudian "diubah" untuk mencocokkan ini — koreksi saya jika saya salah di sana. Bahkan mungkin lebih sederhana bahwa shell hanya "naif" mencoba untuk mencoba mengakses direktori persis seperti yang diinginkan pengguna dan ketika sistem file mengembalikan beberapa jenis kesalahan, shell menampilkan respon yang sesuai.

Namun, yang menarik bagi saya adalah bagaimana proses yang sama bekerja ketika saya menavigasi direktori, yaitu ke orang tua, atau orang tua orang tua.

Mengingat lokasi Documents saya yang tidak diketahui, mungkin "buta" , salah satu dari kemungkinan banyak direktori di seluruh pohon sistem file dengan nama itu, bagaimana cara Unix menentukan di mana saya harus ditempatkan selanjutnya? Apakah itu membuat referensi ke pwd dan memeriksa itu? Jika ya, bagaimana pwd melacak status navigasi saat ini?

Jawaban yang Diterima:

Jawaban lainnya adalah penyederhanaan yang berlebihan, masing-masing hanya menyajikan sebagian dari cerita, dan salah dalam beberapa hal.

Ada dua cara di mana direktori kerja dilacak:

  • Untuk setiap proses, dalam struktur data kernel-space yang mewakili proses tersebut, kernel menyimpan dua referensi vnode ke vnode dari direktori kerja dan direktori root untuk proses tersebut. Referensi sebelumnya diatur oleh chdir() dan fchdir() panggilan sistem, yang terakhir dengan chroot() . Orang dapat melihatnya secara tidak langsung di /proc pada sistem operasi Linux atau melalui fstat perintah di FreeBSD dan sejenisnya:

    % fstat -p $$|head -n 5
    USER     CMD          PID   FD MOUNT      INUM MODE         SZ|DV R/W
    JdeBP    zsh        92648 text /         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 nama jalur beroperasi, itu dimulai pada satu atau yang lain dari vnode yang direferensikan, menurut apakah jalurnya relatif atau absolut. (Ada keluarga …at() panggilan sistem yang memungkinkan resolusi nama jalur untuk dimulai pada vnode yang dirujuk oleh deskriptor file (direktori) terbuka sebagai opsi ketiga.)

    Di Unices mikrokernel, struktur data berada di ruang aplikasi, tetapi prinsip memegang referensi terbuka ke direktori ini tetap sama.

  • Secara internal, di dalam shell seperti Z, Korn, Bourne Again, C, dan shell Almquist, shell tambahan melacak direktori kerja menggunakan manipulasi string dari variabel string internal. Ia melakukan ini setiap kali ada alasan untuk memanggil chdir() .

    Jika seseorang mengubah nama path relatif, itu akan memanipulasi string untuk menambahkan nama itu. Jika seseorang berubah menjadi nama path absolut, string tersebut akan diganti dengan nama baru. Dalam kedua kasus, ini menyesuaikan string untuk menghapus . dan .. komponen dan untuk mengejar tautan simbolik menggantikannya dengan nama yang ditautkan ke mereka. (Ini adalah kode shell Z untuk itu, misalnya.)

    Nama dalam variabel string internal dilacak oleh variabel shell bernama PWD (atau cwd di kulit C). Ini secara konvensional diekspor sebagai variabel lingkungan (bernama PWD ) ke program yang dihasilkan oleh shell.

Kedua metode pelacakan hal ini diungkapkan oleh -P dan -L pilihan ke cd dan pwd perintah bawaan shell, dan perbedaan antara pwd bawaan shell perintah dan keduanya /bin/pwd perintah dan pwd bawaan perintah hal-hal seperti (antara lain) VIM dan NeoVIM.

% mkdir a ; ln -s a b
% (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
% 

Terkait:Mencari editor File GUI alternatif dengan dukungan file besar?

Seperti yang Anda lihat:mendapatkan direktori kerja "logis" adalah dengan melihat PWD variabel shell (atau variabel lingkungan jika bukan program shell); sedangkan mendapatkan direktori kerja "fisik" adalah dengan memanggil getcwd() fungsi perpustakaan.

Pengoperasian /bin/pwd program ketika -L option yang digunakan agak halus. Itu tidak bisa dipercaya nilai PWD variabel lingkungan yang diwarisinya. Bagaimanapun, itu tidak perlu dipanggil oleh shell dan program intervensi mungkin tidak mengimplementasikan mekanisme shell untuk membuat PWD variabel lingkungan selalu melacak nama direktori kerja. Atau seseorang mungkin melakukan apa yang saya lakukan di sana.

Jadi yang dilakukannya adalah (seperti yang dikatakan standar POSIX) periksa apakah nama yang diberikan dalam PWD menghasilkan hal yang sama dengan nama . , seperti yang dapat dilihat dengan jejak panggilan sistem:

% ln -s a c
% (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=/hello/there truss /bin/pwd -L 3>&1 1>&2 2>&3 | grep -E '^stat|__getcwd')
stat("/hello/there",0x7fffffffe730)      ERR#2 'No such file or directory'
__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:hanya memanggil getcwd() jika mendeteksi ketidakcocokan; dan bisa ditipu dengan menyetel PWD ke string yang memang menamai direktori yang sama, tetapi dengan rute yang berbeda.

getcwd() fungsi perpustakaan adalah subjek dalam dirinya sendiri. Tapi untuk presisi:

  • Awalnya itu murni fungsi perpustakaan, yang membangun nama path dari direktori kerja kembali ke root dengan berulang kali mencoba mencari direktori kerja di .. direktori. Itu berhenti ketika mencapai loop di mana .. sama dengan direktori kerjanya atau ketika ada kesalahan saat mencoba membuka .. next berikutnya ke atas. Ini akan menjadi banyak panggilan sistem di balik selimut.
  • Saat ini situasinya sedikit lebih kompleks. Di FreeBSD, misalnya (ini juga berlaku untuk sistem operasi lain), adalah panggilan sistem yang sebenarnya, seperti yang Anda lihat di jejak panggilan sistem yang diberikan sebelumnya. Semua traversal dari direktori kerja vnode hingga root dilakukan dalam satu panggilan sistem, yang memanfaatkan hal-hal seperti akses langsung kode mode kernel ke cache entri direktori untuk melakukan pencarian komponen nama jalur dengan lebih efisien.

    Namun, perhatikan bahwa bahkan pada FreeBSD dan sistem operasi lain tersebut, kernel tidak melacak direktori kerja dengan string.

Menavigasi ke .. sekali lagi merupakan subjek dalam dirinya sendiri. Presisi lain:Meskipun direktori secara konvensional (walaupun, seperti yang telah disinggung, ini tidak diperlukan) berisi .. actual yang sebenarnya dalam struktur data direktori pada disk, kernel melacak direktori induk dari setiap direktori vnode itu sendiri dan dengan demikian dapat menavigasi ke .. vnode dari direktori kerja mana pun. Ini agak rumit oleh mountpoint dan mekanisme root yang berubah, yang berada di luar cakupan jawaban ini.

Selain

Windows NT sebenarnya melakukan hal serupa. Ada satu direktori kerja per proses, ditetapkan oleh SetCurrentDirectory() Panggilan API dan dilacak per proses oleh kernel melalui pegangan file terbuka (internal) ke direktori itu; dan ada satu set variabel lingkungan yang diprogram Win32 (bukan hanya penerjemah perintah, tetapi semua Program Win32) digunakan untuk melacak nama beberapa direktori kerja (satu per drive), menambahkan atau menimpanya setiap kali mereka mengubah direktori.

Terkait:Bagaimana cara menggunakan $? dan tes untuk memeriksa fungsi?

Secara konvensional, tidak seperti sistem operasi Unix dan Linux, program Win32 tidak menampilkan variabel lingkungan ini kepada pengguna. Kadang-kadang orang dapat melihatnya di subsistem mirip Unix yang berjalan di Windows NT, juga dengan menggunakan SET penerjemah perintah perintah dengan cara tertentu.

Bacaan lebih lanjut

  • pwd “. Spesifikasi Basis Grup Terbuka Edisi 7. IEEE 1003.1:2008. Grup Terbuka. 2016.
  • “Resolusi Nama Jalur”. Spesifikasi Basis Grup Terbuka Edisi 7. IEEE 1003.1:2008. Grup Terbuka. 2016.
  • https://askubuntu.com/a/636001/43344
  • Bagaimana file dibuka di unix?
  • untuk apa inode, di FreeBSD atau Solaris
  • Variabel lingkungan yang aneh !::=::di Cygwin
  • Mengapa CDPATH tidak berfungsi seperti yang didokumentasikan dalam manual?
  • Bagaimana cara menyetel zsh untuk menggunakan jalur fisik?
  • Masuk ke direktori yang ditautkan oleh tautan

Linux
  1. Linux – Bagaimana Cara Memeriksa Informasi Struktur Direktori File Unix/linux?

  2. Bagaimana cara mengaktifkan pengindeksan file dan direktori Apache di Linux atau UNIX?

  3. Bagaimana cara kerja perintah 'ls' di Linux/Unix?

  1. Bagaimana menemukan direktori home pengguna di linux atau unix?

  2. Bagaimana saya bisa menemukan file terlama di pohon direktori

  3. Bagaimana cara keluar dari penjelajah file Ranger kembali ke command prompt tetapi tetap mempertahankan direktori saat ini?

  1. Cara Menjaga Kepemilikan Dan Izin File Tetap Utuh Saat Menyalin File Atau Direktori

  2. Cara Menemukan File Terlama Di Pohon Direktori Di Linux

  3. Apa bagian lengket dalam sistem file UNIX? Kapan digunakan?