./ ve ../ dizinleri nedir?


20

Basit bir soru, ama nereye bakacağımdan emin değilim ve google noktalara ve eğik çizgilere yanıt vermiyor.

Sadece (alt klasörler / dosyalar dahil değil) geçerli dizindeki dosya ve dizinlerin sayısını # saymaya çalışıyorum ve farklılaştırmaya çalışıyorum ls -1 | wc -lve ls | wc -laynı görünüyorlar. Baktığım bir site "Bunun ./ ve ../ dizinlerini de saydığını unutmayın." Dedi . ile ilgili ls -1, ve bunun daha önce dizinleri veya bir şey (ki ben istemiyorum) içerir anlamına gelir emin değilim, ama bunu testten gibi görünmüyordu.

Birisi bunlardan hangisinin yalnızca geçerli dizindeki (alt değil) dosya ve dizin sayısını saymak için en uygun olacağını ve ./ ve ../ dizinleri ile ne anlama geldiğini doğrulayabilir mi?


"Bunun aynı zamanda ./ ve ../ dizinlerini de
saydığını unutmayın

Yanıtlar:


15

Unix sistemindeki her dizin (ve muhtemelen diğer tüm sistemler de) en az iki dizin girişi içerir. Bunlar .(geçerli dizin) ve ..(üst dizin). Kök dizin durumunda, bunlar aynı yeri gösterir, ancak diğer herhangi bir dizinde farklıdır. Sen kullanarak kendiniz görebilirsiniz stat, pwdve cd(Linux üzerinde) komutları:

$ cd /
$ stat . .. bin sbin | grep Inode
Device: 802h/2050d      Inode: 2           Links: 27
Device: 802h/2050d      Inode: 2           Links: 27
Device: 802h/2050d      Inode: 548865      Links: 2
Device: 802h/2050d      Inode: 2670593     Links: 2
$ pwd
/
$ cd ..
$ pwd
/
$

Dikkat edin binve sbinher birinin iki bağlantısı vardır. Biri kök dizindeki dizin girişi, diğeri ise .o dizinin içindeki giriş.

lsBir boru ile kullanmak wc -l, ls çıkışındaki satır sayısını saymak için basit bir numaradır. Varsayım, her dosya veya dizinin çıktıda tam olarak bir satır kaplayacağıdır. GNU ls, çıkış terminal dışı olduğunda bunu otomatik olarak yapar; diğerleri -1ise davranışı açıkça açma seçeneğine ihtiyaç duyabilir . girişindeki wc -lsatır ( -l) sayısını sayar ve çıktı verir .

Bu yaklaşımla ilgili sorun, Linux'ta ve Linux'ta geleneksel olarak kullanılan dosya sistemlerinde dosya ve dizin adlarının (bu bağlamda gerçekten bir ve aynı oldukları) yeni satır karakterleri içermesine izin verilmesidir . Bunların varlığında, her iki yöntem de parçalanır - bu girdiler, gerçekte bir olduklarında iki veya daha fazla giriş olarak sayılacaktır.

GNU l'leri kullandığınız sürece, yeni satır karakterleri içeren adlara sahip dizin girişleriniz olmadığı ve ls(örneğin ls -a) için tek takma adların olmadığı sürece , her ikisi de geçerli (veya belirtilen) dizindeki dosya ve dizin sayısını verir. Çoğu insan için bu yeterince iyidir, ancak genel durumda geçerli değildir .

Dizin giriş adlarında olağandışı karakterleri (özellikle yeni satırlar) düzgün bir şekilde işlemeniz gerekiyorsa, -bonlardan kaçmak için ls seçeneğini kullanmanızı öneririm . ls -1bAher dizin girişi adını kendi satırına yazdıracak, olağandışı karakterlerden kaçacak (böylece her dizin girişi bir tane olarak görülecektir), herhangi bir dotfiles ve -directories dahil. Tack wc -ltam bir komut satırı için ls -1bA | wc -l(ama görmezden geçerli dizinde dosya ve dizinleri sayısını bildirir ki .ve ..; aramdaki fark -ave -A), ancak herhangi bir alt dizinleri içine inerler. Herhangi bir nokta dosyasının toplamda sayılmasını istemiyorsanız, -Aparametreyi atlayın ls.


Hem -ave -Aböylece en azından ben yaparım, ben kaçınmak istiyor fark ettik hem bu kadar dosyaları gizli içerir ls -b | wc -l, ama bu sefer doğru cevabı vermek yok. Bu komutla ilgili olarak kopyalayıp yapıştırdığım satır yanlış mı? Doğruysa, bir dizinde 6 dosya veya klasör olduğunda 8 çıktı almamalıyım?
Adam

@Adam evet, muhtemelen hile yapacak ("ls -b | wc -l"); ayrıca, bir girişi tek bir satırda değil, tek bir sütunda tek bir sütunda zorlayan "-1" i (tire + bir numara) kullanabilirsiniz, ancak bu yine de başka bir komuta bağlanırken olur. Yani (imho) "ls -1b | wc -l" olarak bırakırım; ve "sınamak" için "ls -1b" çalıştırın ve satır sayısını sayın, sonra "ls -1b | wc -l" çalıştırın ve sonuçları doğrulayın. (Borularda hata ayıklama / test etme yöntemi budur.)
michael

@Sardathrion, bu SSS oldukça yanıltıcı. Unix dosya sistemi kuralları "garip" değildir; ortak oldukları yerde diğer sistem onları alıyor. Ama tamam. Sonra "dosya komutu tanımlamak için sihirli sayılar kullanır ..." diyor ki bu yanlış: Çok fazla sezgisel tarama kullanıyor. Kitabımda çok güvenilir değil.
vonbrand

@vonbrand: yeterince adil, bağlantı silindi. Sadece yağmaladım ve iyi görünüyordu. İyi olanı bulduğumu biliyorum ama şimdi nerede olduğunu hatırlayamıyorum.
Sardathrion - Monica'yı

1
Yanılıyorsun: . ve .. 1970'lerde UNIX'in tarihi eserleridir ve henüz bir mkdir()sistem çağrısının olmadığı bir zamanın sonucudur . Tüm dosya sistemleri bunlara sahip değildir ve POSIX tarafından gerek duyulmaz ve hatta gerekmez.
schily

6

Konudaki soruyu cevaplamak için:

Unix'te B dizini oluşturulduğunda, başka bir A dizinine (ana dizini) yeni bir giriş olarak eklenir ve B'ye iki giriş eklenir: biri .sabit bağlantı olarak adlandırılır ve biri ..sabit olarak adlandırılır A bağlantısı.

Bunlar, izin verilen dizinlere olan tek sabit bağlantıdır (bazı Unices'in bazı eski sürümleri de rastgele bağlantılara izin vermesine rağmen).

bu nedenle çoğu dosya sisteminde ( btrfsdikkate değer bir istisna olarak), linksbir dizinin sayısı kaç alt dizine sahip olduğunu ( ..girişlerini hesaba katarak) gösterir.

Bir dizini yeniden adlandırırken / taşırken, aynı dizine (farklı bir adla) sahipse, yalnızca içindeki giriş girişi Adeğiştirilir. B .ve ..etkilenmez. Eğer farklı bir dizin yapmak taşırsanız, o zaman ..içinde Bdeğişecektir. Bu, başka bir dizine taşımadığınız sürece (üst dizine yazma erişiminiz olduğunu varsayarak) yazma erişimine sahip olmadığınız bir dizini neden yeniden adlandırabileceğinizi açıklar (aksi takdirde ..girişi değiştirme gereği önler taşıyın).

Ama dikkat: /a/b/../caynı olmayabilir /a/cçünkü /a/bbir olabilir sembolik diğer bazı dizini bağlantısı.

Bunun bir istisnası, bu yolun cdbazı kabuklara komuta verilmesi. Bunlar cdler tedavi etmek .. mantıklı görmezden ..dizinleri girdileri. Karışıklık ve tutarsızlıklara neden olabilecek cd -Pbu özelliği devre dışı bırakmak için, düzgün yazılmış komut dosyalarında sık sık görmenin bir nedeni .

Hariç geçerli dizinde girişlerinin sayısını saymak için .ve ..ile bashbunu yapabilirsiniz:

shopt -s nullglob dotglob
set -- *
echo "$#"

Zsh ile:

f=(*(ND))
echo $#f

portably:

find . ! -name . -prune -print | grep -c /

Biraz kafam karıştı; listelediğiniz her üçü de gerçek sayıya bir tane ekler. Örneğin, bir dizinde 6 dosya veya klasör varsa, 6 değil, 7 çıktılar. Bana göre, ls | wc -lsadece biri gibi görünüyor .ve..
Adam

1
@Adam, lsgizli dosyaları listelemez. Bunlarla ls -Aaynı şeyi elde etmelisin . Eğer, gizli dosyaları saymak çıkarmak istemiyorum EĞER dotglob(partisi yüzünden) veya D(için zsh) veya eklemek ! -name '.*'önce -printiçin find.
Stéphane Chazelas

Evet, aslında dosyaları listeledikten sonra bunu fark ettim. O zaman neden ls | wc -lhala bana doğru cevabı verdiğini ve gizli dosyaları hariç tuttuğunu biliyor musun .& ..?
Adam

1
Adam, Dizininizde, sahip ., ..ve adı başlar ile başka bir dosya .ls ile listede yoksa fakat tarafından olurdu ls -A. Bu yüzden ls | wc -lsize doğru cevabı vermiyor çünkü o gizli dosyayı saymıyor.
Stéphane Chazelas

1
Evet .ve ..a ile başladıklarından beri gizli dosyalardır .. Dotfiles erken uygulama olarak kazara gizli olduğunu açıklayan bir efsane bile var lssadece dışlamak gerekiyordu .ve ..ancak herhangi bir dosya ile başlayan dışlamak için neden bir hata oluştu .. ls | wc -ldosya adları yeni satır karakterleri içeriyorsa çalışmaz.
Stéphane Chazelas

1

Harika bir Linux uzmanı değilim, ama Linux'u biliyorum (16 yıl önce Slackware'de yönetici olarak çalışıyordum :) iyi eski zaman

./ ve ../ dizinleri basit:. geçerli dizin, .. önceki dizin (pwd -local dizin komut-

Onları sayarsa, listenin toplamına 2 eklediklerini, gerçekten özyinelemeyle gitmediğini ve geçerli dizinin altındaki dizini saydığını ve yine geçerli dizinin (.) :) sayıldığını tahmin ediyorum

Yani temelde zaten geçerli dizinde saymak (dosyaları) için 2 değerini ekler düşünüyorum.

Yanılıyorsam herkes beni düzeltir.

Ben sadece yardım etmek için gönderiyorum ve burada kimsenin bu soruya cevap vermediğini gördüm, meşgul olabilirler. Ama sadece deneme ve 10 dosya olup olmadığını görmek ve 12 sayısı almak o zaman bu.


Evet, Adrian doğru:. geçerli dir ve .. hiyerarşinin hemen üstündeki dizindir.
schaiba

.. her zaman ağaçtaki bir önceki dizine gönderme yapmaz: "/" .. de geçerli dizine işaret eder.
Bonsi Scott

çünkü dosya sisteminde / kökünde olabilirsiniz?
Adrian Tanase

Bir dizindeki # dosyaya iki eklerse, neden osx terminalinde test ederken doğru cevabı alıyorum? Örn: 6 dosya veya klasör içeren bir dizin yaptığımda 8 değil, 6 çıktı alacakls | wc -1
Adam

Bunun gizli dosyaları (yani .ds_store) içerdiğini fark ettim, ancak hala doğru cevabı + 2'nin aksine nasıl ls | wc -liçerdiğini .ve ..ne zaman doğru cevabı aldığımı göremiyorum .
Adam
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.