Çıktı dosyası / dev / null olduğunda, tar neden dosya içeriğini atlıyormuş gibi görünüyor?


21

400'den fazla GiB veri içeren bir dizine sahibim. Ben düşündüm basit bir yolu oldu bu yüzden tüm dosyalar, hatasız okunabilir kontrol etmek istedik tariçine o /dev/null. Ancak bunun yerine aşağıdaki davranışı görüyorum:

$ time tar cf /dev/null .

real    0m4.387s
user    0m3.462s
sys     0m0.185s
$ time tar cf - . > /dev/null

real    0m3.130s
user    0m3.091s
sys     0m0.035s
$ time tar cf - . | cat > /dev/null
^C

real    10m32.985s
user    0m1.942s
sys     0m33.764s

Yukarıdaki üçüncü komut zaten çok uzun süre çalıştıktan sonra Ctrl+ tarafından zorla durduruldu C. Ayrıca, ilk iki komut çalışırken, içeren depolama cihazının etkinlik göstergesi .neredeyse her zaman boştaydı. Üçüncü komutla gösterge sürekli yanar, bu da aşırı meşgul olma anlamına gelir.

Böylece tar, çıktı dosyasının ne zaman olduğunu bulabiliyor /dev/null, yani /dev/nulldoğrudan dosyaya yazılan tanıtıcıya açıldığında tar, dosya gövdesi atlanmış gibi görünüyor. ( Dizin içindeki tüm dosyaları 'kırmızı olanı basmak viçin seçenek ekleme ).'tartar

Öyleyse merak ediyorum, bu neden böyle? Bir çeşit optimizasyon mu? Eğer öyleyse, neden tarböyle özel bir durum için bu kadar şüpheli bir optimizasyon yapmak istesin ki ?

Linux 4.14.105’de amd64’de GNU tar 1.26 kullanıyorum.


7
Pratik bir alternatif olarak, gibi bir şey düşünün find . -type f -exec shasum -a256 -b '{}' +. O kalmıyor aslında okumak ve tüm verileri sağlama toplamı, ancak çıkış saklamak varsa, dosyaların içeriği değişmediğini kontrol etmek daha sonra yeniden çalıştırabilirsiniz.
Ilmari Karonen

Şeyleri ölçmek için de kullanabilirsiniz pv: tar -cf - | pv >/dev/null. Bu, sorunu pv
ortadan kaldırır

GNU katranının çok iyi bilinen bir bayan özelliğini vurdun. İstediğini elde gtar -cf /dev/zero ...etmek için kullan .
schily

Yanıtlar:


25

Bu ise belgelenmiş optimizasyon :

Arşiv oluşturulduğunda /dev/null, GNU tar giriş ve çıkış işlemlerini en aza indirmeye çalışır. Amanda yedekleme sistemi, GNU tar ile kullanıldığında, bu özelliği kullanan bir başlangıç ​​boyutlandırma geçişine sahiptir.


4
Ah, bu yüklediğim adam sayfasında anlatılmadı. Bunun info taryerine
denemeliydim

9
Gerçekten adam ve bilgi sayfalarını senkronize
tutmalılar

9
@Ruslan Çoğu GNU yardımcı programında, man sayfası yalnızca kısa bir özet içerir, temelde yalnızca bir şey yapma seçeneğinin olduğunu, ancak seçeneğin adını hatırlamadığınızı hatırladığınızda yeterince iyi olur. Belgelerin tamamı, man sayfalarına iyi bir şekilde çevrilemeyen ve infobir tarayıcıda veya ile HTML olarak kullanılabilen bir biçimdedir .
Gilles 'SO- kötülük yapmayı bırak'


8

Bu, çeşitli programlarda olabilir, örneğin, sadece bir kez kullanırken bu davranışı yaptım cp file /dev/null; Diskimin okuma hızını tahmin etmek yerine, komut birkaç milisaniyeden sonra geri döndü.

Hatırladığım kadarıyla, bu Solaris ya da AIX'teydi, ancak prensip her tür unix-y sistemi için geçerli.

Eski zamanlarda, bir program bir yere bir dosyayı kopyaladığında read, diskten (ya da dosya tanımlayıcısından bahsettiği her neyse) veriyi belleğe ( readgeri döndüğünde her şeyin orada olacağına dair bir garanti ile) alan çağrılar arasında değişir ve writeçağrılar (bu bellek miktarını alır ve içeriği hedefe gönderir).

Bununla birlikte, aynı şeyi başarmanın en az iki yeni yolu var:

  • Linux'ta sistem çağrıları copy_file_range(diğer unix'lere taşınabilir değil) ve sendfile(biraz taşınabilir; başlangıçta ağa bir dosya göndermeyi amaçlıyor, ancak şimdi herhangi bir hedefi kullanabilir). Transferleri optimize etmeye yöneliktirler; Program bunlardan birini kullanıyorsa, çekirdeğin hedefin olduğunu /dev/nullalgılaması ve sistem çağrısını işlemesiz hale getirmesi kolayca düşünülebilir

  • Programlar, mmapbunun yerine dosya içeriğini almak için kullanabilir ; bunun readanlamı, "sistem çağrısı geldiğinde verilerin orada olduğundan emin olun" yerine "bu bellek yığınına erişmeye çalıştığımda verilerin olduğundan emin olun" anlamına gelir. Böylece bir program mmapkaynak dosyayı alabilir ve writeharitalanmış hafızanın bir kısmını çağırır . Ancak, yazma /dev/nullişleminin yazılı verilere erişmesi gerekmediğinden, "orada olduğundan emin olun" koşulu hiç tetiklenmez, bu da dosyanın okunmamasına neden olur.

Gnu katran herhangi kullanır ve emin değil hangi bu iki mekanizmanın o yazılı algıladığında /dev/null, ancak herhangi bir program, sebebi sensin salt hızları kontrol kullanıldığında , birlikte çalıştırılmalıdır | cat > /dev/nullyerine > /dev/null- neden ve | cat > /dev/nullshould olmak kaçınılması diğer tüm durumlarda.


Bence GNU tarbilgi sayfasındaki ima (başka bir cevaba bakınız) bunun için özel bir moda sahip olduğunu ve muhtemelen dosyaları açmadan sadece istatistiklere sahip olduğunu düşünüyorum. Aslında ben sadece tar cf /dev/null foo*birkaç dosyaya baktım ve evet, sadece newfstatat(..., AT_SYMLINK_NOFOLLOW)sistem çağrıları, hatta bir open()zamanı bile güncelleyemedim. Ancak, özel olarak tespit etmek zorunda kalmadan bunun olabileceği mekanizmaları tanımlamak için + 1.
Peter Cordes

Mmap açıklamasında " yazılı verilere erişilsin " yerine " okunan verilere erişilsin mi" okunmalı mı?
Wayne Conrad,

Ayrıca bakınız splice(2)Linux'ta. Aslında, ( Linux'ta kullanılan) cat > /dev/nullile değiştirmek, genel masrafı azaltacaktır. Veya , veya veya ...pv -q > /dev/nullsplice()dd bs=65536 skip=9999999999 2> /dev/nullwc -c > /dev/nulltail -c1 > /dev/null
Stéphane Chazelas
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.