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

14

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

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

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

Синкопированный
источник
Проверьте, можете ли вы использовать tmpfs вместо / tmp: kernel.org/doc/Documentation/filesystems/tmpfs.txt
ott--
Связанный: askubuntu.com/questions/380238/how-to-clean-tmp
Сиро Сантилли 新疆 改造 中心 法轮功 六四 事件

Ответы:

15

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

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). Проблема заключается в том, что запись в каталоге удаляется немедленно, а это означает, что с момента удаления файла новые процессы не смогут открыть файл (так как к нему не прикреплено имя файла).

Подробности см .: /programming/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перед тем, как вы удалите все, что нужно вашей системе!

mreithub
источник
красивый. А как насчет файлов, закрытых длительным процессом, пока он не обновляет их? Если они являются файлами контекста, вы можете потерять контекст процесса (по общему признанию, это не очень умный процесс, но нужно знать ожидаемые побочные эффекты «боковой» /tmp/очистки).
Ник
В этом проблема этого подхода (как я указывал в последнем абзаце). Наилучшим подходом здесь будет afaik - добавить uid / gid или проверки шаблонов файлов (соответственно отредактировал ответ)
mreithub
Должно ли это быть помещено в скрипт cron ...?
CMCDragonkai
@CMCDragonkai Конечно, вы можете поместить это в crontab. Но, как я уже упоминал, могут быть файлы, к которым обращаются, но которые не записываются, и поэтому могут не отфильтровываться этим небольшим скриптом. Вот почему безопаснее сначала распечатать список затронутых файлов, а затем решить, удалять их или нет. Если вы /tmpнаходитесь на отдельном разделе (например, на виртуальном диске), вы можете включить atimeего и использовать -atimeпараметр find.
mreithub
Я планирую сделать это на сервере. Поэтому я не могу быть там, чтобы считать все файлы в TMP все время. Будут ли какие-либо проблемы? Кроме того, я думал, что мы должны были использовать relaytime, а не atime?
CMCDragonkai
3

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

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

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

sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 
Гринго Суаве
источник
В этом /etc/tmpreaper.confфайле, если я установлю оба /tmpи /var/tmpкак каталоги очистки, долго ли вы можете порекомендовать TMPREAPER_TIMEпараметр или максимальную давность файлов tmp, которые нужно удалить? Я слышал, лучше хранить /var/tmpфайлы дольше , чем /tmpфайлы. Но если они могут быть установлены только с одинаковым максимальным возрастом, я понятия не имею.
Сяодун Ци
2

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

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

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

Клавдий
источник
0

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

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

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

Я согласен с вышесказанным, чтобы добавить к нему, хотя - я всегда запускаю 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)
SeaPhor
источник
2
SU случайным образом расставляет посты - так что нет ни выше, ни ниже. На какой пост вы ссылаетесь?
Подмастерье Компьютерщик
0

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

Соломон Уцко
источник
Предложение сделать что-то «и надеюсь, что ничего не сломается» на самом деле не отвечает ОП «Есть ли безопасный способ сделать это. Возможно, вы могли бы уточнить, почему ваше предложение безопасно?»
bertieb
@bertieb Хороший вопрос. Я думаю, это, вероятно, безопасно, если он не запускается от имени пользователя root, но ...
Соломон Уко