Как безопасно очистить папку 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
: ищите открытые файлы в / tmpawk '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)