Gerçek dizin boyutu (du dışı) nasıl elde edilir?


17

UNIX / Linux standart araçlarını kullanarak gerçek dizin boyutunu nasıl bulabilirim?

Alternatif soru: Nasıl alabilirim du bana gerçek dizin boyutu (değil disk kullanımı) göstermek için?

İnsanlar "boyut" teriminin farklı tanımlarına sahip görünüyorlar: "Dizin boyutu" tanımım, bu dizindeki tüm normal dosyaların toplamıdır.

Dizin inode'un büyüklüğünü veya dosyaların ilgili dosya sisteminde ne aldığını (bloklar * blok boyutu) umursamıyorum. Her biri 1 bayt olan 3 dosya içeren bir dizin, 3 baytlık bir dizine sahiptir (tanımıma göre).

Dizin boyutunu du kullanarak hesaplamak güvenilmez görünüyor.
Örneğin, mkdir foo && du -b foo"4096 foo", 0 bayt yerine 4096 bayt bildirir. Çok büyük dizinlerde, bildirilen dizin boyutu du -hs100 GB (!) Ve daha fazlası (sıkıştırılmış dosya sistemi) ile kapatılabilir.

Peki, gerçek dizin boyutunu elde etmek için ne (araç / seçenek) kullanılmalıdır?


Yeni lokasyonda hangi dosya sistemi kullanılıyor - xfsherhangi bir şans eseri mi?
Sergey Vlasov


Ve eğer yeni FS'niz gerçekten XFS ise, büyük ölçüde artan disk kullanımı, muhtemelen disk kullanım pahasına dosya parçalanmasını azaltan agresif ön tahsisattan kaynaklanmaktadır .
Sergey Vlasov

Yanıtlar:


8

İşte Unix standart araçlarını (POSIX) kullanarak insan tarafından okunabilen bir dizin boyutu görüntüleyen bir betik.

#!/bin/sh
find ${1:-.} -type f -exec ls -lnq {} \+ | awk '
BEGIN {sum=0} # initialization for clarity and safety
function pp() {
  u="+Ki+Mi+Gi+Ti+Pi+Ei";
  split(u,unit,"+");
  v=sum;
  for(i=1;i<7;i++) {
    if(v<1024) break;
    v/=1024;
  }
  printf("%.3f %sB\n", v, unit[i]);
}
{sum+=$5}
END{pp()}'

Örneğin:

$ ds ~        
72.891 GiB

Ve şimdi tüm önerilen eksik başka bir seçenek buldum lsburada çağırmaları: -q. Bu seçenek olmadan, bazı dosya adları yeni satır karakterleri içeriyorsa, kod kırılır. Gerçekten güvenilir kabuk senaryoları yazmak çok zor…
Sergey Vlasov

@SergeyVlasov Gönderdiğim komut dosyası, yalnızca fazladan satırları yok sayarak bu tür dosyaları bozmamalı. Tek sorun, dikkatlice hazırlanmış bir dosyanın, sayısal bir değer içeren beşinci kolon ile ekstra bir çizgiye sahip olması durumunda ortaya çıkar. Öneriniz gerçekten bu durumdan kaçınacaktır. İpucu için teşekkürler, komut dosyası güncellendi.
jlliagre

Mükemmel cevap Size +1 efendim
ehime

Bu en güvenilir çözümlerden biridir. İçinde boşluk veya tırnak bulunan dosya adlarıyla çalışır ve insan tarafından okunabilen bir boyut yazdırır.
temel6

@KIAaze Kodumu incelediğiniz ve düzelttiğiniz için teşekkür ederiz!
jlliagre

8

Bazı sürümleri, disk kullanımı yerine görünür bir boyut gösterme duargümanını destekler --apparent-size. Yani emriniz:

du -hs --apparent-size

Du için hazırlanan man sayfalarından Ubuntu 12.04 LTS dahil:

--apparent-size
      print apparent sizes,  rather  than  disk  usage;  although  the
      apparent  size is usually smaller, it may be larger due to holes
      in (`sparse') files, internal  fragmentation,  indirect  blocks,
      and the like

1
çalışmıyor: boş dirler için biraz yer bildirin
Karl Forner

1
bu benim için çalıştı.
bağdaştırıcı

2
Farklı dosya sistemlerindeki dizinleri karşılaştırırken önemli ölçüde farklı boyutlar verir. Örneğin, aynı klasör zfs dosya sisteminde 290Gb boyutunda ve 324Gb exFat boyutundadır. Yukarıdaki çözümler aynı büyüklüğü verir.
Pixus.ru

4

Sadece bir alternatif kullanarak ls:

ls -nR | grep -v '^d' | awk '{total += $5} END {print total, "Total"}'

ls -nR: -ngibi -l, ancak sayısal UID'leri ve GID'leri listele ve -Ralt dizinleri tekrar tekrar listele .

grep -v:Eşleşmeyen çizgileri seçmek için eşleşme duygusunu ters çevirin. (-v POSIX tarafından belirtilmiştir.). '^ d'dizinleri hariç tutacaktır.

Ls komutu: http://linux.about.com/od/commands/l/blcmdl1_ls.htm

Man Grep: http://linux.die.net/man/1/grep

EDIT :

Öneri @ Sergey Vlasov.


Kullanımı -nseçeneği lsyerine -l, çünkü (gösteri UID / yerine isimleri GID numaralar) güvenlidir kullanıcı ve grup adları boşluk içerebilir (eğer mesela winbindya sssdbir Windows etki sistemi birleştirmek için kullanılır, sizin gibi grup adlarını alabilirsiniz domain users) . Ayrıca, kullanıcı ve grup adlarını aramaya gerek olmadığından daha hızlı olmalıdır.
Sergey Vlasov

Teşekkürler, bu bulmak -exec ls'den çok daha hızlı!
gpothier

4

duGNU coreutils'e sahip olduğunuzu varsayarak , bu komutun, dosya sayısında herhangi bir sınırlama olmaksızın, bir dizindeki rastgele normal dosya sayısının toplam görünür boyutunu hesaplaması gerekir:

find . -type f -print0 | du -scb --files0-from=- | tail -n 1

İçinde bazı hardlinklenmiş dosyalar varsa ve her hardlink'i ayrı olarak saymak istiyorsanız (varsayılan olarak sadece bir defa birden fazla hardlink sayar) -lseçeneği ekleyin .dudu

Düz ile en önemli fark du -sb, özyinelemeli duaynı zamanda farklı dosya sistemleri tarafından farklı bildirilen dizin boyutlarını sayar; Bundan kaçınmak için, findkomut yalnızca normal dosyaları iletmek için kullanılır du. Diğer bir fark, sembolik bağların göz ardı edilmesidir (sayılmaları gerekiyorsa, findkomutun ayarlanması gerekir).

Bu komut aynı zamanda normalden daha fazla bellek tüketecektir du -sb, çünkü yalnızca birden fazla sabit bağlantıya sahip dosyaları hatırlama davranışının aksine , --files0-from=FILEmake dustore aygıtını kullanmak ve işlenen tüm dosyaların sayısını inode etmek. (Bu -lseçenek, birden çok kez sabit bağlantıları saymak için kullanılıyorsa sorun değildir , çünkü aygıt ve inode numaralarını kaydetmenin tek nedeni, önceden işlenmiş olan hardlink dosyalarını atlamaktır.)

Toplam boyutun insan tarafından okunabilir bir temsilini elde etmek istiyorsanız, sadece -hseçeneği ekleyin (bu dusadece bir kez başlatıldığı için çalışır ve önerilen diğer cevapların aksine, toplam boyutun kendisini hesaplar):

find . -type f -print0 | du -scbh --files0-from=- | tail -n 1

veya (eğer bazı etkilerinin -bgeçersiz kıldığından endişeleniyorsanız -h)

find . -type f -print0 | du -sc --apparent-size -h --files0-from=- | tail -n 1

FreeBSD için ne yapacağını emin değil - her ne kadar -bmuhtemelen yerini olabilir -A -B 1, orada hiçbir eşdeğerdir --files0-from=-ve kullanan xargsdosya listesi daha büyük olması durumunda bazı geçici çözümler gerekecektir ARG_MAX(ve insanlar tarafından okunabilir çıkış için bazı harici bir çözüm).
Sergey Vlasov

3

İstediğiniz tek şey, dosyaların boyutu ise, dizinlerin kapladığı alan hariç

find . -type f -print0 | xargs -0 du -scb | tail -n 1

@SergeyVlasov, bundan daha fazla dosyanız varsa, bunun başarısız olacağını belirtti argmax. Bundan kaçınmak için şöyle bir şey kullanabilirsiniz:

find . -type f -exec du -sb '{}' \; | gawk '{k+=$1}END{print k}'

1
Dizin onlar) (execve üzerine sınırda argümanlar boyutuna uymayan pek çok dosya içeriyorsa, bu komut sessizce bir yanlış sonuç verecektir - bu durumda xargsçağıracağı dubirden çok kez ve her çağırma sadece kendi kısmı için genel toplamı yazdırılır tam dosya listesinin ardından tail, sadece son kısmın toplam boyutunu gösterir.
Sergey Vlasov

1
@SergeyVlasov iyi bir nokta, bunu hiç düşünmemiştim, teşekkürler, cevap güncellendi.
terdon
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.