Linux'ta tmp klasörünü güvenli bir şekilde temizleme


15

Tam olarak tmpfs / tmp, 2GB için RAM kullanıyorum. Normalde bu yeterlidir, ancak bazen süreçler orada dosyalar oluşturur ve kendilerinden sonra temizleyemezler. Bu, kaza yaparlarsa olabilir. Bu yetim tmp dosyalarını silmem gerekiyor, yoksa gelecekteki işlem / tmp'de alan bitecek.

Nasıl çöp toplama / tmp güvenli bir şekilde? Bazı insanlar son değişiklik zaman damgasını kontrol ederek bunu yaparlar, ancak bu yaklaşım güvensizdir, çünkü bu dosyalara hala ihtiyaç duyan uzun süren işlemler olabilir. Daha güvenli bir yaklaşım, son değişiklik zaman damgası koşulunu hiçbir işlemin dosya için dosya tanıtıcısı olmaması koşuluyla birleştirmektir. Bu yaklaşımı veya güvenli olan başka bir yaklaşımı somutlaştıran bir program / senaryo / vb. Var mı?

Bu arada, Linux / Unix, bir çökme olsa bile, oluşturma işlemi sona erdiğinde oluşturulan dosyanın silindiği oluşturma ile bir dosya açma moduna izin veriyor mu?


/ Tmp yerine tmpfs kullanıp kullanamayacağınızı kontrol edin: kernel.org/doc/Documentation/filesystems/tmpfs.txt
ott--

Yanıtlar:


15

Böyle bir şey denemek isteyebilirsiniz:

find /tmp -mtime +7 -and -not -exec fuser -s {} ';' -and -exec echo {} ';'

find, belirli ölçütlerle eşleşen dosyaları bulmak için kullanılır.

  • -mtime +7 sadece 7 günden daha eski dosyaları seçer (başka bir değer kullanabilirsiniz)
  • -exec fuser -s {} ';'eskilik ölçütlerine uyan her dosya için füzeri sessiz modda çağırır. fuser, şu anda erişilen her dosya için 0 (= true) ve erişilmeyen dosyalar için 1 (= false) döndürür. Sadece erişilemeyenlerle ilgilendiğimiz için bunun -notönüne-exec
  • -exec echo {} ';'ölçütlerle eşleşen tüm dosya adlarını yazdırmanız yeterlidir. -exec rm {} ';'burada kullanmak isteyebilirsiniz , ancak bu hala kullanımda olan bazı dosyaları silebileceğinden, önce basit bir yankı yapmak daha güvenli olur.
  • edit: Kazara etkileri önlemek için temizleme gibi efektleri belirli dosya desenleri veya kullanıcı kimlikleriyle sınırlamak -name 'foo*.bar'veya -uid 123kısıtlamak isteyebilirsiniz .

Son noktaya kadar: Yalnızca bir kez yazılan (örneğin sistem önyüklemesinde) ancak sık sık (örneğin herhangi bir X-oturumu-çerezi) yazılan dosyalar olabileceğini düşünün. Bu nedenle, yalnızca hatalı programlarınız tarafından oluşturulan dosyaları etkilemek için bazı ad denetimleri eklemenizi öneririz.

edit2: Son sorunuza: Hiçbir işlem için açık bir tanıtıcı olmadıkça (en azından yerel linux dosya sistemleri için) bir dosya diskten silinmez. Sorun, dizin girdisinin hemen kaldırılmasıdır; bu, dosyayı kaldırdığınız andan itibaren yeni işlemlerin artık dosyayı açamayacağı anlamına gelir (dosya adı eklenmediğinden).

Ayrıntılar için bkz. Https://stackoverflow.com/questions/3181641/how-can-i-delete-a-file-upon-its-close-in-c-on-linux

edit3: Peki ya bütün süreci otomatikleştirmek istersem?

Dediğim gibi, bir kez yazılan ve sonra arada bir okunan dosyalar olabilir (örneğin, X oturum çerezleri, PID dosyaları, vb.). Bunlar bu küçük kaldırma komut dosyası tarafından hariç tutulmayacak (bu yüzden echodosyaları silmeden önce ilk önce bir test çalıştırması yapmak isteyebilirsiniz ).

Güvenli bir çözüm uygulamanın bir yolu kullanmaktır atime.
atimeher dosyanın en son erişildiği zamanı saklar. Ancak bu dosya sistemi seçeneği genellikle devre dışıdır çünkü performans etkisi oldukça fazladır ( bu blog'a göre % 20-30 bölgedeki bir yere göre ). Var relatime, ancak erişim zamanı mtimedeğiştiğinde yazar , bu yüzden bu bize yardımcı olmaz.

Kullanmak istiyorsanız , tüm sistem üzerindeki performans etkisinin çok büyük olmaması için ayrı bir bölüme (ideal olarak bir ramdisk) atimesahip olmanızı öneririm /tmp.

atimeEtkinleştirildikten sonra , tek yapmanız gereken -mtimeyukarıdaki komut satırındaki parametreyi değiştirmek -atime.
Bunu kaldırabilirsiniz -not -exec fuser -s {} ';', ancak emin olmak için orada saklıyorum (uygulamaların dosyaları uzun süre açık tutması durumunda).

Ancak echosisteminizin hala ihtiyaç duyduğu şeyleri kaldırmadan önce komutu kullanarak test etmeyi unutmayın !


Güzel. Uzun süredir devam eden bir işlem tarafından kapatılmayan dosyalar güncellenmiyorsa ne olacak? Bağlam dosyalarıysa, işlem bağlamını kaybedebilirsiniz (kuşkusuz, çok akıllı bir işlem değil; ancak bir 'yanal' /tmp/temizlemenin beklenen yan etkilerini bilmeniz gerekir ).
nik

Bu yaklaşımın problemi budur (son paragrafta belirttiğim gibi). Buradaki en iyi yaklaşım, uid / gid veya dosya deseni kontrolleri eklemek olacaktır (buna göre cevabı düzenledi)
mreithub

Bu bir cron senaryosuna konulmalı mı?
CMCDragonkai

@CMCDragonkai Elbette bunu crontab'a koyabilirsiniz. Ancak belirttiğim gibi, erişilen ancak yazılmayan dosyalar olabilir ve bu nedenle bu küçük komut dosyası tarafından filtrelenmeyebilir. Bu nedenle önce etkilenen dosyaların listesini yazdırmak ve daha sonra bunları silmek isteyip istemediğinize kendiniz karar vermek daha güvenlidir. Eğer /tmpayrı bir bölümdeyseniz (örneğin bir ramdisk), bunu etkinleştirebilir atimeve -atimeparametresini kullanabilirsiniz find.
mreithub

Bunu bir sunucuda yapmayı planlıyorum. Bu nedenle her zaman tmp içindeki tüm dosyaları saymak için orada olamam. Herhangi bir sorun olur mu? Ayrıca, reimim'i atime değil de kullanmamız gerektiğini düşündüm.
CMCDragonkai

4

Kendinizi yuvarlamayın.

Debian / Ubuntu'nun tmpreaper'ı var, muhtemelen diğer bölgelerde de mevcut.

# tmpreaper - cleans up files in directories based on their age

sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 

In /etc/tmpreaper.confben de ayarlarsanız dosya /tmpve /var/tmptemizleme dizinleri gibi, sürece tavsiye yapabilirsiniz TMPREAPER_TIMEparametresi veya tmp dosyaları önce maksimum kaldırılacak? /var/tmpDosyalar için dosyalardan daha uzun yaş tutmanın daha iyi olduğunu duydum /tmp. Ancak, sadece aynı maksimum yaşla kurulabilirlerse, hiçbir fikrim yok.
Xiaodong Qi

2

Sorunuzun son kısmı ile ilgili:

'If-this-if-die-i-die' açık / oluşturma modunun var olduğunu düşünmeme rağmen, bir işlem oluşturulduktan sonra doğrudan söz konusu dosya için bir tanıtıcı açık kaldığı sürece bir dosyayı güvenli bir şekilde silebilir. Çekirdek daha sonra dosyayı diskte tutar ve dosyayı açan son işlem biter bitmez (çökme veya normalde olsun), dosyanın kapladığı alan serbest bırakılır.

Bazı işlemlerin bazen / tmp'yi temizlemediği sorunun genel bir yolu için, örneğin burada veya burada açıklanan montaj ad alanlarına bir göz atmanızı öneririm . Söz konusu işlem bir sistem arka plan programı ise, özel / tmp dosya sistemlerine izin veren systemd ve yerel özelliği ilgi çekici olabilir.



0

Bundan daha eski dosyaların listesini alın, bu listeden herhangi bir şey tarafından açılan dosyaları hariç tutun:

find /tmp -mtime +7 |\
    egrep -v "`lsof -n +D /tmp | awk 'NR>1 {print $9}'| tr \\n \|`" 

lsof -n +D /tmp: / tmp dosyasında açık dosyaları arayın
awk 'NR>1 {print $9}': başlıklar hariç yalnızca lsof çıktısının dokuzuncu sütununu yazdırın
tr \\n \|: yeni satırı çubukla değiştirin (egrep'te VEYA)
egrep -v "foo|moo|bar": foo, moo veya bar içermeyen baskı satırları


0

Buna katılıyorum, yukarıdakilere katılıyorum- Her zaman çalıştırıyorum lsof +L1 | grep tmpve "silinmiş" tmp dosyalarına tutunan işlemleri öldürüyor veya yeniden başlatıyorum: EXAMPLE-

# lsof +L1 | grep tmp
xfce4-ter  1699  user   32u   REG    8,6      192     0 818552 /tmp/vte966VLX (deleted)
chrome     3301  user  138u   REG    8,6    16400     0 818547 /tmp/etilqs_Z0guKD7p6ork9iG (deleted)

2
SU gönderileri rastgele düzenler - böylece yukarıda veya aşağıda yoktur. Hangi yayına atıfta bulunuyorsunuz?
Journeyman Geek

0

Yapabilirsin rm -rf /tmp/*ve hiçbir şeyin bozulmamasını umabilirsin ...


1
Gerçekten OP adlı cevap vermez bir şey "ve umut bir şey sonları" yapmak için öne süren "bir var olan güvenli yolu bunu yapmak Belki de öneri güvenlidir neden olarak ayrıntı verebilir.?
bertieb

@bertieb İyi bir nokta. Kök olarak çalıştırılmazsa muhtemelen güvende, ama ...
Solomon Ucko
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.