Cara membersihkan folder tmp dengan aman di Linux

14

Saya menggunakan RAM untuk tmpfs / tmp saya, 2GB, tepatnya. Biasanya, ini sudah cukup tetapi kadang-kadang, proses membuat file di sana dan gagal untuk membersihkan sendiri. Ini bisa terjadi jika mereka crash. Saya perlu menghapus file-file tmp yatim ini atau proses selanjutnya akan kehabisan ruang di / tmp.

Bagaimana saya bisa dengan aman mengumpulkan / tmp sampah? Beberapa orang melakukannya dengan memeriksa cap waktu modifikasi terakhir, tetapi pendekatan ini tidak aman karena mungkin ada proses yang berjalan lama yang masih membutuhkan file-file itu. Pendekatan yang lebih aman adalah menggabungkan kondisi timestamp modifikasi terakhir dengan kondisi bahwa tidak ada proses yang memiliki pegangan file untuk file tersebut. Apakah ada program / skrip / etc yang mewujudkan pendekatan ini atau pendekatan lain yang juga aman?

Secara kebetulan, apakah Linux / Unix memungkinkan mode pembukaan file dengan kreasi di mana file yang dibuat dihapus ketika proses pembuatan berakhir, bahkan jika itu dari crash?

Disinkronkan
sumber
Periksa apakah Anda dapat menggunakan tmpfs alih-alih / tmp: kernel.org/doc/Documentation/filesystems/tmpfs.txt
ott--
Terkait: askubuntu.com/questions/380238/how-to-clean-tmp
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:

15

Anda mungkin ingin mencoba sesuatu seperti itu:

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

find digunakan untuk menemukan file yang sesuai dengan kriteria tertentu.

  • -mtime +7 hanya memilih file yang lebih lama dari 7 hari (Anda dapat menggunakan nilai lain)
  • -exec fuser -s {} ';'memanggil fuser dalam mode senyap untuk setiap file yang cocok dengan kriteria ketuaan. fuser mengembalikan 0 (= true) untuk setiap file yang telah diakses saat ini dan 1 (= false) untuk yang belum diakses. Karena kami hanya tertarik pada yang belum diakses, kami menempatkan -notdi depan ini-exec
  • -exec echo {} ';'cukup cetak semua nama file yang cocok dengan kriteria. Anda mungkin ingin menggunakannya di -exec rm {} ';'sini, tetapi karena ini dapat menghapus beberapa file yang masih digunakan, saya pikir lebih aman untuk melakukan gema sederhana terlebih dahulu.
  • sunting: Anda mungkin ingin menambahkan sesuatu seperti -name 'foo*.bar'atau -uid 123membatasi efek pembersihan ke pola file atau ID pengguna tertentu untuk menghindari efek yang tidak disengaja.

Ke poin terakhir: Pertimbangkan bahwa mungkin ada file yang hanya ditulis sekali (misalnya pada boot sistem) tetapi sering membaca (misalnya cookie X-sesi apa pun). Karena itu saya sarankan menambahkan beberapa pemeriksaan nama hanya mempengaruhi file yang dibuat oleh program Anda yang salah.

sunting2: Untuk pertanyaan terakhir Anda: File tidak akan dihapus dari disk sampai tidak ada proses yang memiliki pegangan terbuka (setidaknya untuk sistem file linux asli). Masalahnya adalah bahwa entri direktori dihapus segera yang berarti bahwa sejak Anda menghapus file tidak ada proses baru dapat membuka file lagi (karena tidak ada nama file yang melekat padanya).

Untuk detail, lihat: /programming/3181641/how-can-i-delete-a-file-upon-its-close-in-c-on-linux

sunting3: Tetapi bagaimana jika saya ingin mengotomatiskan seluruh proses?

Seperti yang saya katakan, mungkin ada file yang ditulis sekali dan kemudian dibaca sesekali (misalnya cookie sesi X, file PID, dll.). Itu tidak akan dikecualikan oleh skrip penghapusan kecil ini (yang merupakan alasan mengapa Anda mungkin ingin melakukan uji coba echoterlebih dahulu sebelum benar-benar menghapus file).

Salah satu cara untuk mengimplementasikan solusi yang aman adalah menggunakan atime.
atimemenyimpan waktu setiap file diakses terakhir kali. Tapi opsi sistem file itu sering dinonaktifkan karena memiliki dampak kinerja yang cukup (menurut blog ini di wilayah 20-30%). Ada relatime, tetapi yang satu itu hanya menulis waktu akses jika mtimesudah berubah, jadi yang ini tidak akan membantu kita.

Jika Anda ingin menggunakan atime, saya sarankan untuk memiliki /tmppartisi yang terpisah (idealnya ramdisk) sehingga dampak kinerja pada keseluruhan sistem tidak terlalu besar.

Setelah atimediaktifkan, yang harus Anda lakukan adalah mengganti -mtimeparameter pada baris perintah di atas dengan -atime.
Anda mungkin dapat menghapusnya -not -exec fuser -s {} ';', tetapi saya akan menyimpannya di sana hanya untuk memastikan (jika aplikasi membuka file untuk jangka waktu yang lama).

Tetapi perlu diingat untuk menguji perintah menggunakan echosebelum Anda akhirnya menghapus hal-hal yang masih dibutuhkan sistem Anda!

mreithub
sumber
bagus. Bagaimana dengan file yang ditutup oleh proses yang berjalan lama sementara tidak memperbarui? Jika mereka adalah file konteks, Anda dapat kehilangan konteks proses (memang, ini bukan proses yang sangat cerdas; tetapi orang perlu mengetahui efek samping yang diharapkan dari /tmp/pembersihan 'lateral' ).
nik
Itulah masalah dari pendekatan ini (seperti yang saya tunjukkan pada paragraf terakhir). Pendekatan terbaik di sini akan afaik adalah dengan menambahkan uid / gid atau memeriksa pola file (diedit jawabannya sesuai)
mreithub
Haruskah ini dimasukkan ke dalam skrip cron ...?
CMCDragonkai
@ CMCDragonkai Tentu saja Anda bisa memasukkan ini ke crontab. Tetapi seperti yang saya sebutkan mungkin ada file yang diakses tetapi tidak ditulis dan karena itu mungkin tidak disaring oleh skrip kecil ini. Itu sebabnya lebih aman untuk mencetak daftar file yang terpengaruh terlebih dahulu dan kemudian memutuskan sendiri apakah akan menghapusnya atau tidak. Jika Anda /tmpberada di partisi yang terpisah (mis. Ramdisk), Anda dapat mengaktifkannya atimedan menggunakan -atimeparameter find.
mreithub
Saya berencana melakukan ini di server. Karena itu saya tidak dapat hadir untuk menghitung semua file dalam tmp setiap saat. Apakah akan ada masalah? Juga saya pikir kami seharusnya menggunakan relatime bukan atime?
CMCDragonkai
4

Jangan menggulung sendiri.

Debian / Ubuntu memiliki tmpreaper, mungkin juga tersedia di dist lain.

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

sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 
Gringo Suave
sumber
Dalam /etc/tmpreaper.conffile tersebut, jika saya menetapkan keduanya /tmpdan /var/tmpsebagai direktori pembersihan, dapatkah Anda merekomendasikan TMPREAPER_TIMEparameter atau jumlah maksimum file tmp yang akan dihapus? Saya telah mendengar bahwa lebih baik menyimpan file lebih lama /var/tmpdaripada /tmpfile. Tetapi jika mereka hanya dapat diatur dengan usia maks yang sama, saya tidak tahu.
Xiaodong Qi
2

Mengenai bagian terakhir dari pertanyaan Anda:

Meskipun saya tidak berpikir bahwa mode buka / kreasi 'delete-this-if-die-die' ada, suatu proses dapat langsung menghapus file secara aman setelah membuatnya, asalkan tetap menangani file yang dibuka. Kernel kemudian akan menyimpan file di disk dan segera setelah proses terakhir yang telah membuka file keluar (baik karena crash atau normal), ruang yang ditempati oleh file akan dibebaskan.

Untuk cara umum mengatasi masalah bahwa beberapa proses kadang-kadang tidak membersihkan / tmp, saya akan menyarankan untuk melihat mount namespaces, dijelaskan, misalnya di sini atau di sini . Jika proses yang dimaksud adalah daemon sistem, systemd dan fitur aslinya untuk memungkinkan sistem file pribadi / tmp mungkin menarik.

Claudius
sumber
0

Dapatkan daftar file yang lebih lama dari itu, kecualikan file yang dibuka oleh apa pun dari daftar itu:

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

lsof -n +D /tmp: cari file yang terbuka di / tmp
awk 'NR>1 {print $9}': cetak hanya kolom kesembilan dari output lsof, tidak termasuk header
tr \\n \|: ganti baris baru dengan bar (ATAU di egrep)
egrep -v "foo|moo|bar": baris cetak TIDAK mengandung foo atau moo atau bar

Ярослав Рахматуллин
sumber
0

Saya setuju dengan hal di atas, untuk menambahkannya - saya selalu menjalankan lsof +L1 | grep tmpdan mematikan atau memulai kembali proses yang menahan file tmp "dihapus": 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)
SeaPhor
sumber
2
SU secara acak mengatur posting - jadi tidak ada yang di atas atau di bawah. Posting mana yang Anda maksud?
Journeyman Geek
0

Anda hanya bisa melakukan rm -rf /tmp/*dan berharap tidak ada yang rusak ...

Solomon Ucko
sumber
1
Menyarankan untuk melakukan sesuatu "dan berharap tidak ada yang rusak" tidak benar-benar menjawab OP "adalah ada cara yang aman untuk melakukan ini. Mungkin Anda bisa menguraikan mengapa saran Anda aman?
bertieb
@bertieb Poin bagus. Saya kira itu mungkin aman jika tidak dijalankan sebagai root, tapi ...
Solomon Ucko