İlerlemeyi de görürken, bir dizinden milyarlarca dosyayı silmek


36

Resmî olarak tüm JPEG dosyaları olan milyarlarca dosyayı içeren 30 TB'luk bir dizine sahibim. Bunun gibi her dosya klasörünü siliyorum:

sudo rm -rf bolands-mills-mhcptz

Bu komut sadece çalışır ve çalışıyor olsun veya olmasın hiçbir şey göstermez.

Dosyaları siliyor ya da komutun o andaki durumunu görmek istiyorum.


19
Cevap vermemek: Bazen saklamak istediğiniz şeyleri yedeklemek, biçimlendirmek ve geri yüklemek istediğiniz şeyleri daha hızlı yapabilirsiniz. Diğer cevaplar: unix.stackexchange.com/questions/37329/…
Eric Towers 17

2
Hangi dosyaların kaldırıldığını bilmek yerine, yalnızca bir ilerleme fikrini istiyorsanız, "df / dev / sd_whatever_the_drive_is" komutunu çalıştırabilirsiniz.
jamesqf

11
Milyarlarca dosyayı tek bir dizinde nasıl buldunuz ?
Monica

1
@MichaelHampton Ancak dosyalar ayrı bir veri kümesi değilse, uzun sürebilir. (
ZFS'de

5
Milyarlarca dosya, ha? Dene rm -ri. Eğlenceli olacak!
OldBunny2800

Yanıtlar:


98

Sen kullanabilirsiniz rm -vsahip olmak rmdosya silinmiş başına bir satır yazdırın. Bu yolla rmdosyaların gerçekten silinmeye çalıştığını görebilirsiniz . Ancak milyarlarca dosyanız varsa, tüm göreceğiniz bu rmhala çalışıyor demektir. Kaç dosyanın silindiği ve ne kadarının kaldığı hakkında hiçbir fikriniz olmaz.

Araç pv, bir ilerleme tahmininde size yardımcı olabilir.

http://www.ivarch.com/programs/pv.shtml

Burada çağırmak şekli şöyledir rmile pvörnek çıkışı ile

$ rm -rv dirname | pv -l -s 1000 > logfile
562  0:00:07 [79,8 /s] [====================>                 ] 56% ETA 0:00:05

Bu tartışmalı örnekte dosyalar pvolduğunu söyledim 1000. pv562 çıktısı, 562'nin zaten silinmiş olduğunu, geçen sürenin 7 saniye olduğunu ve tamamlanma tahmininin 5 saniye içinde olduğunu gösterir.

Bazı açıklamalar:

  • pv -lpvbayt yerine newlines saymayı yapar
  • pv -s numberpvtoplamın ne olduğunu söyler , böylece size bir tahminde bulunabilir.
  • logfileSonuna yapılan yönlendirme temiz çıktı içindir. Aksi halde, durum çizgisi pvile olan çıktı karışır rm -v. Bonus: silinenlerden bir günlük dosyası alacaksınız. Ancak dosyanın çok büyük olacağına dikkat edin. /dev/nullBir günlüğe ihtiyaç duymuyorsanız da yönlendirebilirsiniz .

Dosya sayısını almak için bu komutu kullanabilirsiniz:

$ find dirname | wc -l

Milyarlarca dosya varsa bu da uzun zaman alabilir. pvBurada ne kadar sayıldığını görmek için de kullanabilirsiniz.

$ find dirname | pv -l | wc -l
278k 0:00:04 [56,8k/s] [     <=>                                              ]
278044

İşte 278k dosyaları saymak için 4 saniye sürdü diyor. Sonundaki ( 278044) kesin sayım , çıktısıdır wc -l.

Saymayı beklemek istemiyorsanız, dosya sayısını tahmin edebilir veya tahmin pvetmeden kullanabilirsiniz :

$ rm -rv dirname | pv -l > logfile

Bunun gibi bitirmek için bir tahminde bulunmayacaksınız ama en azından kaç dosyanın silinmiş olduğunu göreceksiniz. Günlük /dev/nulldosyasına ihtiyacınız yoksa, yönlendirin .


nitpick:

  • gerçekten ihtiyacın var sudo
  • Genellikle rm -ryinelemeli olarak silmek için yeterlidir. hayır için ihtiyaç rm -f.

5
Güzel kullanımı pv, milyarlarca dosyayı saymanın çok pahalı olmadığını varsayarak ;-). (Ölçmesi gerektiği kadar zaman alabilir rm!)
Stephen Kitt

7
@StephenKitt Windows dosya programı hakkında beni (ve diğer birçok insanı) gerçekten sinirlendiren şey: bu, her zaman , hatasız, silinmeden önce dosyaların sayısını ve boyutlarını sayar; sürücü işlemciden çok daha yavaş değilse, neredeyse Gerçek silme sürece!
wizzwizz4 17

@ wizzwizz4 Gerçekten! Bundan daha fazlası var olduğunu IIRC olsa - bu o çeklerin olabilir silmeden önce her şeyi silmek şey , "hep ya hiç" olmak silme şansını artırmak için. Yıllar önce, Windows için bir dosya sistemi sürücüsü yazdım, Explorer'ın silme şeklinin de dahil olduğu da dahil olmak üzere başa çıkmamız gereken birkaç tuhaflık vardı, ancak ayrıntıları hatırlayamıyorum. (Bir klasör oluşturmanın yeni klasörde bir dosya yazmayı ve silmeyi içerdiğini hatırlıyorum!)
Stephen Kitt

7
@StephenKitt Belki yanılıyorum ama disk erişiminin yanı sıra terminal çıkışındaki tıkanıklık da değil mi? Giriş pvçubuğuna, girişine rağmen saniyede yalnızca bir kez yenilendiğini düşünüyorum . Bu yüzden, terminal her saniye bir ton yerine sadece bir satır göstermelidir. pvyalnızca karşılaştığı her yeni satır için bir sayaç artırması gerekir; bu, hat sarma işleminden daha hızlı olmalı ve bir terminalde bir çizgiyi görüntülemek için değil. Bunun pvgibi çalıştırmanın dosya kaldırma işleminin basitlemeden daha hızlı olmasına neden olduğunu düşünüyorum rm -rv.
JoL,

1
@skywinderrm -rv dirname | pv -l -s $(find dirname | wc -l) > logfile
lesmana

28

Check out Lesmana yanıtını , çok daha iyi benim daha var - özellikle son pvçok daha uzun orijinal sessiz daha sürmez örnek, rmbelirttiğiniz takdirde /dev/nullyerine logfile.

rmSeçeneğinizi desteklediğini varsayarak (muhtemelen Linux çalıştırdığınızdan beri gerçekleşir), aşağıdaki modda ayrıntılı olarak çalıştırabilirsiniz -v:

sudo rm -rfv bolands-mills-mhcptz

Bazı yorum yapanlar tarafından belirtildiği gibi, terminal tarafından üretilen ve görüntülenen çıktı miktarı nedeniyle bu çok yavaş olabilir. Bunun yerine çıktıyı bir dosyaya yönlendirebilirsiniz:

sudo rm -rfv bolands-mills-mhcptz > rm-trace.txt

ve boyutunu izleyin rm-trace.txt.


5
Bu aslında üretilen ve bir terminale dönüştürülen tüm çıktılar nedeniyle silme işlemini yavaşlatabilir :)
rackandboneman

2
Tabii ki yavaşlayacaktır. Bir dosyaya milyarlarca satır yazmak sıfır zamanda gerçekleşmez.
user207421

23

Diğer bir seçenek de, dosya sistemindeki düşüş sayısındaki dosya sayısının izlenmesidir. Başka bir terminalde çalıştırın:

watch  df -ih   pathname

Kullanılan inode sayımı rmilerledikçe azalacaktır . (Dosyalar çoğunlukla birden fazla bağlantıya sahip değilse, örneğin ağaç oluşturulduysa cp -al). Bu, dosya sayısı (ve dizinler) açısından silme ilerlemesini izler. dfolmadan -ikullanılan alan açısından izleyecektir.

iostat -x 4Saniyede G / Ç işlemlerini görmek için de koşabilirsiniz (kiB / s'nin yanı sıra bu, saf meta veri G / Ç için çok da önemli değildir).


rmŞu anda hangi dosyaların üzerinde çalıştığını merak ediyorsanız, bir bağlantı ekleyebilir straceve unlink()(ve getdents) sistem çağrılarının terminalinizde patladığı gibi izleyebilirsiniz . örn sudo strace -p $(pidof rm). Şunları yapabilirsiniz ^cstrace ayırmak için rmonu kesmeden.

rm -rDizini sildiği ağaca değiştirirse unuturum ; eğer öyleyse bakabilirsin /proc/<PID>/cwd. Onun /proc/<PID>/fdsize ne olduğunu görmek için bu bakmak böylece kudreti genellikle dizin, açık fd olan rmsüreç şu anda bakıyor.


2
df -ihgerçekten de rmilerlemenin izlenmesinin güzel ve ucuz bir yoludur .
Stephen Kitt

BTW, bu kullanılan inode sayısının her zaman sıfır olduğu BTRFS'de çalışmaz. :( FAT32 için de aynı, ancak muhtemelen /bootEFI sistem bölümünüzde milyarlarca dosyanız yok
Peter Cordes

4

Yukarıdaki cevaplar her kullanım sırasında rm, rmGeçenlerde gözlenen olarak çıkarılırken aslında arşiv .tar bir silerek daha az zaman aldı aslında ~, dosyaların büyük sayıda silme oldukça yavaş 100K dosya olabilir. Bu aslında sorduğunuz soruyu yanıtlamamasına rağmen, bu sorunun en iyi çözümü, dosyalarınızı silmek için bu sorunun yanıtlanan yanıtlarından biri gibi farklı bir yöntem kullanmak olabilir .

Kişisel favori yöntemim kullanmaktır rsync -a --delete. Bu yöntemin , yazarın derlemeniz gereken bir C programı yazdığı, bu sorunun en çok cevaplanan cevabı üzerinde kullanım kolaylığına değeceği kadar hızlı bir şekilde çalıştığını biliyorum . (Bunun, işlenen her dosyanın stdout'a gönderileceğini unutmayın, bunun gibi rm -rv; bu işlemi şaşırtıcı bir miktarda yavaşlatabilir. Bu çıktısını istemiyorsanız rsync -aq --delete, çıktıyı bir dosyaya kullanın veya yeniden yönlendirin.)

Bu cevabın yazarı şöyle diyor:

Program şimdi (sistemimde) 1000000 dosyayı 43 saniyede silecek. Buna en yakın program 60 saniye süren rsync -a --delete'dir (bu da silmeleri sırayla yapar ancak verimli bir dizin araması yapmaz).

Bunun amaçlarım için yeterince iyi olduğunu buldum. Ayrıca, en azından ext4 kullanıyorsanız, bu yanıttan potansiyel olarak önemli:

Öngörü olarak, kişi etkilenen dizini silmeli ve sonra yeniden düzenlemelidir. Dizinler yalnızca boyut olarak çoğalır ve dizinin boyutu nedeniyle içinde bulunan birkaç dosyada bile düşük performans göstermeye devam eder.


huh, verimli olacağını rmve / veya olacağını umuyordum find --delete. Silme sırasında b-ağacı dengelemelerini önlemek için sıralama düzeninde silme hakkında ilginç bir nokta. Bunun ne kadarının diğer dosya sistemleri için geçerli olduğundan emin değilsiniz. XFS ayrıca, dizin başına milyonlarca dosya için de iyi değildir. BTRFS hakkında IDK, ancak böyle bir şey için iyi olabileceği izlenimi altındayım.
Peter Cordes

Bu ikinci alıntı dosya sisteminin türüne bağlı değil mi ...
Menasheh 4'16

@Menasheh İyi nokta, bunu cevabımı düzenledim.
Hitechcomputergeek

3

Yapabileceğiniz şeylerden biri rm, arka planda işlemi başlatmak (çıktı olmadan, bu yüzden yavaşlamayacak) ve sonra basit bir (a) komutuyla ön planda izlemek olacaktır :

pax> ( D=/path/to/dir ; rm -rf $D & while true ; do
...>   if [[ -d $D ]] ; then
...>     echo "$(find $D | wc -l) items left"
...>   else
...>     echo "No items left"
...>     break
...>   fi
...>   sleep 5
...> done )

27912 items left
224 items left
No items left

pax> _

find/wcAçılan, istediğiniz birimler verebilen herhangi bir araç ile değiştirilebilir.


(a) Nükleer fiziğe, Riemann hipotezine veya karımı Xmas için ne alacağına göre , nispeten basit.


0

Bir süre önce, satırların yazdırılma oranını yazdırmak için bir şeyler yazdım. Koşabilir rm -rfv | ./counterve sn / dak başına satır basar. Doğrudan bir ilerleme olmamasına rağmen, ilerleme hızı hakkında bir geri bildirim verecektir, belki rmbir ağ dosya sistemine ya da benzeri bir ürüne dolanabilirsiniz?

Kodun bağlantısı burada:

http://www.usenix.org.uk/code/counter-0.01.tar.gz

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.