Diğer cevaplar, her biri hikayenin sadece bölümlerini sunan, aşırı basitleştirmelerdir ve birkaç noktada yanlıştır.
Çalışma dizininin izlendiği iki yol vardır :
- Her işlem için, bu işlemi temsil eden çekirdek-alan veri yapısında, çekirdek, çalışma dizininin vnodlarına ve o işlemin kök dizinine iki vnode referansı depolar. Eski başvuru ile ayarlanır
chdir()
ve fchdir()
sistem çağrıları, ikincisi chroot()
. Bunları dolaylı /proc
olarak Linux işletim sistemlerinde ya da fstat
FreeBSD ve benzeri komutlarla görebilirsiniz:% fstat -p $$ | head -n 5
KULLANICI CMD PID FD MONTAJ MODELİ SZ | DV R / W
JdeBP zsh 92648 metin / 24958 -r-xr-xr-x 702360 r
JdeBP zsh 92648 ctty / dev 148 crw - w ---- puan / 4 rw
JdeBP zsh 92648 wd / usr / ana sayfa / JdeBP 4 drwxr-xr-x 124 r
JdeBP zsh 92648 kökü / 4 drwxr-xr-x 35 r
%
Yol adı özünürlüğü çalıştığında, yolun göreceli veya mutlak olmasına bağlı olarak başvurulan vnotlardan biri veya diğerinden başlar. ( …at()
Açık (dizin) dosya tanıtıcısının üçüncü bir seçenek olarak başvuru yaptığı vnode'da yol adı çözümlemesinin başlamasını sağlayan bir sistem çağrısı ailesi vardır .)
Mikro çekirdek Unices'de veri yapısı uygulama alanındadır, ancak bu dizinlere açık referanslar tutma prensibi aynı kalmaktadır.
- Dahili olarak, örneğin Z, Korn, Bourne Yine, C ve Almquist kabuk kabukları içinde, kabuk ek bir iç dize değişkeni dize işlemleri kullanarak çalışma dizini izler. Bunu, aramaya neden olduğu zaman yapar
chdir()
.Biri göreceli bir yol adına değişirse, o ismi eklemek için dizgiyi değiştirir. Eğer biri mutlak yol ismine geçerse, dizeyi yeni isimle değiştirir. Her iki durumda da, dizeyi çıkarmak .
ve ..
bileşenleri kaldırmak ve onları bağlantılı isimleri ile değiştirmek yerine sembolik bağları kovalamak için ayarlar . ( Örneğin , Z kabuğunun bunun kodu .)
İç string değişkenindeki isim, PWD
(veya cwd
C kabuklarında) isimli bir kabuk değişkeni ile izlenir . Bu, geleneksel olarak PWD
kabuk tarafından oluşturulan programlara bir ortam değişkeni (adında ) olarak verilir.
İzleme şeylerin Bu iki yöntem ile ortaya çıkar -P
ve -L
seçenekler cd
ve pwd
kabuk dahili komutları ve yerleşik kabukları arasındaki farklılıklardan pwd
komutlar ve her iki /bin/pwd
komuta ve yerleşik pwd
gibi şeylerin komutları (diğerleri arasında) VIM ve NeoVIM.
% mkdir a;
% -sab % ( cdb ; pwd; / bin / pwd; printenv PWD)
/ Usr / home / JdeBP / b
/ Usr / home / JdeBP / a
/ Usr / home / JdeBP / b
% (cdb; pwd -P; / bin / pwd -P)
/ Usr / home / JdeBP / a
/ Usr / home / JdeBP / a
% (cdb; pwd-L; / bin / pwd -L)
/ Usr / home / JdeBP / b
/ Usr / home / JdeBP / b
% (cd-Pb; pwd; / bin / pwd; printenv PWD)
/ Usr / home / JdeBP / a
/ Usr / home / JdeBP / a
/ Usr / home / JdeBP / a
% (cd b; PWD = / merhaba / orada / bin / pwd -L)
/ Usr / home / JdeBP / a
%
Gördüğünüz gibi: "mantıksal" çalışma dizinini edinmek, PWD
kabuk değişkenine (ya da kabuk programı değilse çevre değişkeni) bakmaktan ibarettir; "fiziksel" çalışma dizinini edinmek ise getcwd()
kitaplık işlevini çağırmaktan ibarettir.
Seçenek kullanıldığında /bin/pwd
programın çalışması -L
biraz incedir. Bu güvenemiyorum değerini PWD
miras ettiğini ortam değişkeni. Sonuçta, bir kabuk tarafından çağrılması gerekmedi ve araya giren programların kabuğun PWD
çevre değişkenini her zaman çalışan dizinin adını izlemesini sağlayan mekanizma uygulamamış olabilir . Ya da biri orada yaptığımı yapabilir.
Öyleyse, (POSIX standardının dediği gibi) verilen PWD
adın .
, sistem çağrısı izlemesiyle görülebileceği gibi, adla aynı şeyi verdiğini kontrol edin :
% 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, boyut = 2, blksize) = 131072)) = 0 (0x0)
/ Usr / home / JdeBP / b
% (cd b; PWD = / usr / yerel / 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, boyut = 2 , blksize = 131072}) = 0 (0x0)
__getcwd ("/ usr / home / JdeBP / a", 1024) = 0 (0x0)
/ Usr / home / JdeBP / a
% (cd b; PWD = / merhaba / truss / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ("/ hello / there", 0x7fffffffe730) ERR # 2 'Böyle bir dosya veya dizin yok'
__getcwd ("/ usr / home / JdeBP / a", 1024) = 0 (0x0)
/ Usr / home / JdeBP / a
% (cd b; PWD = / usr / ana sayfa / JdeBP / c makas / bin / pwd -L 3> & 1 1> & 2 2> & 3 | grep -E '^ stat | __getcwd')
stat ("/ usr / home / JdeBP / c ", {mod = drwxr-xr-x, inode = 120932, boyut = 2, blksize = 131072}) = 0 (0x0)
stat (". ", {Mode = drwxr-xr-x, inode = 120932 , size = 2, blksize = 131072}) = 0 (0x0)
/ Usr / home / JdeBP / c
%
Gördüğünüz gibi: yalnızca getcwd()
bir uyuşmazlık tespit ederse çağırır ; ve PWD
aslında aynı dizini adlandıran bir dize ayarlayarak , ancak farklı bir yolla kandırılabilir .
getcwd()
Kütüphane işlevi kendi başına bir konudur. Ancak précis için:
Gezinmek ..
yine kendi başına bir konudur. Başka bir yöntem: Dizinler geleneksel olarak (her ne kadar önceden belirtilmiş olsa da, zorunlu değildir ), her ne kadar ..
diskteki dizin veri yapısında bir gerçek içeriyorsa da , çekirdek her dizinin vnode'sinin ana dizinini izler ve böylece ..
herhangi bir dizinin içine gidebilir. çalışma dizini. Bu, bu cevabın kapsamı dışında olan bağlama noktası ve değişen kök mekanizmaları tarafından biraz karmaşıktır.
bir kenara
Windows NT aslında benzer bir şey yapar. SetCurrentDirectory()
API çağrısı tarafından ayarlanan ve işlem başına çekirdeğin bu dizine (dahili) bir açık dosya tanıtıcısı aracılığıyla izlenen işlem başına tek bir çalışma dizini vardır; ve Win32 programlarının (yalnızca komut yorumlayıcıları değil, tüm Win32 programlarını da içeren) birden fazla çalışma dizininin (sürücü başına bir tane) isimlerini takip etmek için kullandıkları, her değiştirdiklerinde dizine ekleyen veya üzerine yazdıkları bir ortam değişkenleri kümesi vardır .
Geleneksel olarak, Unix ve Linux işletim sistemlerinde olduğu gibi, Win32 programları bu ortam değişkenlerini kullanıcılara göstermez. Bazen bunları Windows NT üzerinde çalışan Unix benzeri alt sistemlerde de görebilir, ancak komut yorumlayıcıların SET
komutlarını belirli bir şekilde kullanarak.
daha fazla okuma