Как безопасно очистить папку tmp в Linux

Я использую оперативную память для моих tmpfs /tmp, 2 ГБ, если быть точным. Обычно этого достаточно, но иногда процессы создают там файлы и не могут выполнить очистку после себя. Это может произойти, если они потерпят крах. Мне нужно удалить эти потерянные tmp файлы, иначе в будущем / tmp не хватит места.

Как я могу безопасно собрать мусор / TMP? Некоторые люди делают это, проверяя отметку времени последнего изменения, но этот подход небезопасен, поскольку могут существовать длительные процессы, которым все еще нужны эти файлы. Более безопасный подход - объединить условие отметки времени последней модификации с условием, что ни у одного процесса нет дескриптора файла для файла. Есть ли программа / скрипт / и т.д., которые воплощают этот подход или какой-то другой подход, который также безопасен?

Кстати, разрешает ли Linux/Unix режим открытия файла с созданием, при котором созданный файл удаляется при завершении процесса создания, даже если это происходит из-за сбоя?

8 ответов

Решение

Вы можете попробовать что-то вроде этого:

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

find используется для поиска файлов, которые соответствуют определенным критериям.

  • -mtime +7 выбираются только файлы старше 7 дней (вы можете использовать любое другое значение)
  • -exec fuser -s {} ';' вызывает fuser в режиме без вывода сообщений для каждого файла, который соответствует критериям устаревания. fuser возвращает 0 (=true) для каждого файла, к которому обращались в данный момент, и 1 (= false) для недоступных. Поскольку нас интересуют только недоступные, мы ставим -not перед этим -exec
  • -exec echo {} ';' просто печатает все имена файлов, соответствующие критериям. вы можете использовать -exec rm {} ';' вместо этого здесь, но так как это может удалить некоторые все еще используемые файлы, я думаю, что безопаснее сначала сделать простое эхо.
  • редактировать: вы можете добавить что-то вроде -name 'foo*.bar' или же -uid 123 ограничить эффекты очистки конкретными шаблонами файлов или идентификаторами пользователей, чтобы избежать случайных эффектов.

К последнему пункту: Учтите, что могут быть файлы, которые записываются только один раз (например, при загрузке системы), но часто читаются (например, любой файл X-session-cookie). Поэтому я рекомендую добавить некоторые проверки имен, чтобы они влияли только на файлы, созданные неисправными программами.

edit2: К вашему последнему вопросу: файл не будет удален с диска, пока ни у какого процесса не будет открытого дескриптора к нему (по крайней мере, для родных файловых систем linux). Проблема заключается в том, что запись в каталоге удаляется немедленно, а это означает, что с момента удаления файла новые процессы больше не смогут открыть файл (так как к нему не прикреплено имя файла).

Подробности см.: https://stackoverflow.com/questions/3181641/how-can-i-delete-a-file-upon-its-close-in-c-on-linux

edit3: Но что, если я хотел бы автоматизировать весь процесс?

Как я уже сказал, могут быть файлы, которые записываются один раз, а затем читаются время от времени (например, файлы cookie сеанса X, файлы PID и т. Д.). Они не будут исключены этим небольшим скриптом удаления (по этой причине вы можете захотеть выполнить тестовый запуск с echo сначала, прежде чем фактически удалять файлы).

Одним из способов реализации безопасного решения является использование atime,
atime хранит время последнего доступа к каждому файлу. Но эта опция файловой системы часто отключена, потому что она имеет некоторое влияние на производительность (согласно этому блогу где-то в 20-30% регионе). Там в relatime, но тот пишет время доступа только если mtime изменился, так что этот нам не поможет.

Если вы хотите использовать atime Я бы рекомендовал иметь /tmp на отдельном разделе (в идеале, на виртуальном диске), чтобы влияние на производительность системы не было слишком значительным.

однажды atime включен, все, что вам нужно сделать, это заменить -mtime параметр в приведенной выше командной строке с -atime,
Вы можете удалить -not -exec fuser -s {} ';', но я бы оставил его там просто для уверенности (в случае, если приложения сохраняют файлы открытыми в течение длительного периода времени).

Но имейте в виду, чтобы проверить команду, используя echo прежде чем вы удалите все, что нужно вашей системе!

Не катай свои собственные.

У Debian/Ubuntu есть tmpreaper, он, вероятно, доступен и на других дисках.

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

sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 

По поводу последней части вашего вопроса:

Хотя я не думаю, что существует режим открытия / создания "delete-this-if-I-die", процесс может безопасно удалить файл непосредственно после его создания, если он сохраняет дескриптор указанного файла открытым. Затем ядро ​​сохранит файл на диске, и как только последний процесс, открывший файл, выйдет (будь то сбой или обычно), пространство, занимаемое файлом, будет освобождено.

Для общего решения проблемы, заключающейся в том, что некоторые процессы иногда не очищают /tmp, я бы посоветовал взглянуть на пространства имен монтирования, описанные, например, здесь или здесь. Если рассматриваемый процесс является системным демоном, systemd и его нативная функция, позволяющая использовать частные / tmp файловые системы, могут представлять интерес.

Получите список файлов старше, чем это так, исключите файлы, которые открыты чем-либо из этого списка:

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

lsof -n +D /tmp: ищите открытые файлы в / tmp
awk 'NR>1 {print $9}': вывести только девятый столбец вывода lsof, исключая заголовки
tr \\n \|: заменить новую строку на строку (ИЛИ в egrep)
egrep -v "foo|moo|bar": печатать строки, не содержащие foo, moo или bar

Вы могли бы просто сделать rm -rf /tmp/* и надеюсь, что ничего не сломается...

использовать встроенныйtmpfiles.dвместо. Проверьте этот ответ: /questions/457967/obedinenie-1600-mgts-i-1333-mgts-ram/457969#457969

Я проверяю это на Ubuntu 16.10. Я могу подтвердить, что редактирование /etc/default/rcS больше не имеет никакого эффекта, и файлы в tmp удаляются при перезагрузке, независимо от того, что вы поместили в этот файл. Как отмечают другие, tmpreaper больше не используется.

Я думаю, что правильный ответ: Ubuntu 16.10 имеет новую настройку. Существует папка /etc/tmpfiles.d, описанная на странице руководства «tmpfiles.d». В этой папке следует поместить файл конфигурации, чтобы контролировать, следует ли удалять /tmp. Это то, что я делаю, чтобы перезагрузки не удаляли файлы в /tmp, если им не исполнилось 20 дней:

#/etc/tmpfiles.d/tmp.conf

d /tmp 1777 root root 20d Замените «20d» на «-», если вы никогда не хотите, чтобы файлы удалялись. Это моя лучшая попытка, эта справочная страница почти непроницаема для деталей.

Преимущество новой настройки заключается в том, что очиститель файлов по-прежнему может работать, даже если система не перезагружается (как в случае с постоянно включенным сервером). Это большой плюс, я считаю.

Для GUI попробуйте это; http://bleachbit.sourceforge.net/

очищает и скрабы. режим предварительного просмотра.

Я согласен с вышесказанным, чтобы добавить к нему, хотя я всегда бегаю lsof +L1 | grep tmp и либо уничтожить, либо перезапустить процессы, удерживающие "удаленные" файлы tmp: ПРИМЕР-

# 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)
Другие вопросы по тегам