Katranın dosyalar üzerinde çalışma sırası nasıl belirlenir?


15
$ touch dir/{{1..8},{a..p}}
$ tar cJvf file.tar.xz dir/
dir/
dir/o
dir/k
dir/b
dir/3
dir/1
dir/i
dir/7
dir/4
dir/e
dir/a
dir/g
dir/2
dir/d
dir/5
dir/8
dir/c
dir/n
dir/f
dir/h
dir/6
dir/l
dir/m
dir/j
dir/p

Alfabetik olmasını beklerdim. Ama görünüşe göre öyle değil. Formül nedir, burada mı?

Yanıtlar:


14

Gibi @samiam belirtmiştir liste yoluyla yarı rasgele sırada size iade edilir readdir(). Sadece aşağıdakileri ekleyeceğim.

Döndürülen liste dizin sırası dediğim şeydir. Daha eski dosya sistemlerinde, sıra genellikle dizinin tablosundaki dosya girişlerinin eklendiği oluşturma sırasıdır. Elbette buna bir uyarı var, bir dizin girişi silindiğinde, bu giriş daha sonra geri dönüştürülür, böylece saklanan sonraki dosyalar önceki girişin yerini alacaktır, bu nedenle sipariş artık yalnızca oluşturma süresine göre değişmeyecektir.

Dizin veri yapılarının bir arama ağacına veya karma tablosuna dayandığı modern dosya sistemlerinde, sipariş pratik olarak tahmin edilemez.

Örnekler

Dokunma komutunuzu çalıştırdığınızda oluşturulan dosyalara bakınca, aşağıdaki düğümlerin atandığını gösterir.

$ touch dir/{{1..8},{a..p}}
$ stat --printf="%n -- %i\n" dir/*
dir/1 -- 10883235
dir/2 -- 10883236
dir/3 -- 10883242
dir/4 -- 10883243
dir/5 -- 10883244
dir/6 -- 10883245
dir/7 -- 10883246
dir/8 -- 10883247
dir/a -- 10883248
dir/b -- 10883249
dir/c -- 10883250
dir/d -- 10883251
dir/e -- 10883252
dir/f -- 10883253
dir/g -- 10883254
dir/h -- 10883255
dir/i -- 10883256
dir/j -- 10883299
dir/k -- 10883302
dir/l -- 10883303
dir/m -- 10883311
dir/n -- 10883424
dir/o -- 10883426
dir/p -- 10883427

Dolayısıyla, touch tarafından kullanılan küme ayracı genişlemesinin dosya adlarını alfabetik sırayla oluşturduğunu ve böylece HDD'ye yazıldığında sıralı inode numaraları atandığını görebiliriz. (Ancak bu, dizindeki sıralamayı etkilemez.)

Koşu tarbirden çok kez birden çok kez çalıştıran beri Listeye bir düzen olduğunu gösterir gibi görünmektedir komutunu aynısını listesine her seferinde verir. Burada 100 kez çalıştırdım ve daha sonra koşuları karşılaştırdım ve hepsi aynı.

$ for i in {1..100};do tar cJvf file.tar.xz dir/ > run${i};done
$ for i in {1..100};do cmp run1 run${i};done
$ 

Söyledikten dir/esonra stratejik olarak sil ve yeni bir dosya eklersek dir/ee, bu yeni dosyanın daha dir/eönce dizin girişleri tablosunda işgal ettiği yeri aldığını görebiliriz .

$ rm dir/e
$ touch dir/ee

Şimdi çıktıyı foryukarıdaki döngüden birinden , sadece birinciden koruyalım.

$ mv run1 r1A

Şimdi komutu tekrar 100 kez forçalıştıracak döngüyü yeniden çalıştırırsak tarve bu ikinci çalıştırmayı bir öncekiyle karşılaştırırsak:

$ sdiff r1A run1
dir/                                dir/
...
dir/c                               dir/c
dir/f                               dir/f
dir/e                             | dir/ee
dir/o                               dir/o
dir/2                               dir/2
...

Bunun dizinler tablosunda yerini dir/eealdığını fark ettik dir/e.


Vay be, bu gerçekten harika bir cevap. Bir dizin verildiğinde, katranın alt öğelerini hangi sırayla işleyeceğini görmek için herhangi bir yol var mı? Bundan gerçekten emin değilim, ama aşağıdakiler size nasıl bakıyor? stat --printf='%i\t-- %n\n' * | sort -n | sed 's/.*\t-- //'
John

2
Bence dosya sistemine bağımlı. Ben dosya karma ya da bazı tür (yani dosya sistemi dinamik düğümler oluşturur beri, farklı bir duyu eski ReiserFS emir onları var) sırasına göre dizerek bir btree tipi dosya sistemini tahmin edebilirsiniz
Samiam

1
@samiam - sağda, bu cevap 'dizin sırası' nın 'dizinin tablosundaki dosya girişlerinin eklendiği oluşturma sırası olduğunu' iddia eder ve sonra bunun doğru olmadığını gösteren tar dosyası içeriğinin parçalarını gösterir. Mevcut Linux ext * dosya sistemleri dahil olmak üzere birçok dosya sistemi, bazı eski dosya sistemleri gibi basit sıralı tabloları değil, dizin yapılarında ağaçları ve / veya karmaları kullanır.
Michał Politowski

3
@John ls -for ls -Uorfind -maxdepth 1

1
@John -fbayrağı eski Unix'ten geliyor. Amacı hızlı olmaktı. Sıralama, nokta dosyalarının atlanmasını ve diğer birkaç şeyi devre dışı bıraktı. -UBayrak başka yan etkiler olmaksızın devre dışı sıralamaya olanak tanıyan bir GNU yeniliktir.

8

readdir()temelde. Tar dosyaları dizinde ne olduğunu bulduğunda, doğrudan yoluyla listeleyen bir dosya için çekirdek sorar opendir()izledi readdir(). readdir()dosyaları belirli bir sırada döndürmez; dosyaların sıralanma şekli, Linux çekirdeği tarafından kullanılan dosya sistemine bağlıdır.

Ne yazık ki, taralt dizinlerdeki dosyaları sıralamak için bir seçenek değildir (bir tane eklemek okuyucu için bir alıştırma olarak bırakılmıştır).


1
Onları kendi inode değeri dayalı alır olsun merak ediyordum?
slm

1
@slm glibc'nin sonunda üzerinden filtrelediği f_op->iterateçağrı, dosya sistemine özgü bir uygulama ile eşlenir. Daha yüksek bir düzeyde fs uygulama döndürür yeniden hiçbir şey göremiyorum . readdir()getdents()dirent
Matt

@slm Hayır, inode değerinin dizin sırası üzerinde etkili olacağı bir dosya sistemini hiç duymadım.
Gilles 'SO- kötü olmayı bırak
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.