Como limpar a pasta tmp com segurança no Linux

12

Eu uso RAM para o meu tmpfs / tmp, 2GB, para ser exato. Normalmente, isso é suficiente, mas, às vezes, os processos criam arquivos e não fazem a limpeza após eles mesmos. Isso pode acontecer se eles falharem. Eu preciso excluir esses arquivos tmp órfãos ou então o processo futuro ficará sem espaço no / tmp.

Como posso coletar / tmp com segurança no lixo? Algumas pessoas fazem isso verificando a data e a hora da última modificação, mas essa abordagem não é segura porque pode haver processos de longa execução que ainda precisam desses arquivos. Uma abordagem mais segura é combinar a condição de registro de data e hora da última modificação com a condição de que nenhum processo tenha um identificador de arquivo para o arquivo. Existe um programa / script / etc que incorpora essa abordagem ou alguma outra abordagem que também seja segura?

Por acaso, o Linux / Unix permite um modo de abertura de arquivo com a criação, em que o arquivo criado é excluído quando o processo de criação termina, mesmo que seja de uma falha?

    
por Syncopated 03.11.2012 / 17:22

7 respostas

14

Você pode querer tentar algo assim:

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

find é usado para encontrar arquivos que correspondam a determinados critérios.

  • -mtime +7 apenas seleciona arquivos com mais de 7 dias (você pode usar qualquer outro valor)
  • -exec fuser -s {} ';' chama o fusor no modo silencioso para todos os arquivos que correspondem aos critérios de oldness. O fusor retorna 0 (= true) para cada arquivo que foi acessado agora e 1 (= false) para os não acessados. Como estamos interessados apenas nos que não foram acedidos, colocamos um -not na frente deste -exec
  • -exec echo {} ';' apenas imprime todos os nomes de arquivos correspondentes aos critérios. talvez você queira usar -exec rm {} ';' aqui, mas como isso pode excluir alguns arquivos ainda em uso, acho que é mais seguro fazer um eco simples primeiro.
  • edit: Você pode adicionar algo como -name 'foo*.bar' ou -uid 123 para limitar os efeitos da limpeza a padrões de arquivo ou IDs de usuário específicos para evitar efeitos acidentais.

Para o último ponto: considere que pode haver arquivos que são gravados apenas uma vez (por exemplo, na inicialização do sistema), mas lidos com frequência (por exemplo, qualquer cookie de sessão X). Por isso, recomendo adicionar algumas verificações de nomes para afetar apenas arquivos criados por seus programas defeituosos.

edit2: À sua última pergunta: Um arquivo não será excluído do disco até que nenhum processo tenha um identificador aberto (pelo menos para sistemas de arquivos linux nativos). O problema é que a entrada de diretório é removida imediatamente, o que significa que a partir do momento em que você remover o arquivo, nenhum novo processo poderá abrir o arquivo (já que não há nenhum nome de arquivo anexado a ele).

Para detalhes, consulte: link

edit3: Mas e se eu quisesse automatizar todo o processo?

Como eu disse, pode haver arquivos que são gravados uma vez e depois lidos de vez em quando (por exemplo, cookies de sessão X, arquivos PID, etc.). Eles não serão excluídos por este pequeno script de remoção (que é a razão pela qual você pode querer fazer um teste com echo antes de realmente deletar arquivos).

Uma maneira de implementar uma solução segura é usar atime .
atime armazena a hora em que cada arquivo foi acessado pela última vez. Mas essa opção do sistema de arquivos geralmente é desabilitada porque tem bastante impacto no desempenho (de acordo com este blog em algum lugar na região de 20-30%). Há relatime , mas esse só grava o tempo de acesso se mtime foi alterado, então este não nos ajudará.

Se você quiser usar atime , recomendo ter /tmp em uma partição separada (idealmente um disco virtual) para que o impacto no desempenho de todo o sistema não seja muito grande.

Quando atime estiver habilitado, tudo o que você precisa fazer é substituir o parâmetro -mtime na linha de comando acima por -atime .
Você pode remover o -not -exec fuser -s {} ';' , mas eu o manteria lá apenas para ter certeza (caso os aplicativos mantenham arquivos abertos por um longo período de tempo).

Mas lembre-se de testar o comando usando echo antes de acabar removendo as coisas que seu sistema ainda precisa!

    
por 03.11.2012 / 17:43
3

Não rola sozinho.

Debian / Ubuntu tem mais rapidez, provavelmente está disponível em outras dists também.

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

sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 
    
por 13.11.2014 / 05:39
2

Em relação à última parte da sua pergunta:

Embora eu não ache que exista um modo aberto / de criação 'delete-this-se-eu-morrer', um processo pode excluir um arquivo com segurança diretamente após criá-lo, desde que ele mantenha um identificador para o arquivo mencionado. abrir. O kernel manterá o arquivo no disco e assim que o último processo que abriu o arquivo sair (seja por travamento ou normalmente), o espaço ocupado pelo arquivo será liberado.

Para uma maneira geral de contornar o problema que alguns processos às vezes não limpam / tmp, sugiro dar uma olhada nos namespaces de montagem, descritos, por exemplo aqui ou aqui . Se o processo em questão for um daemon do sistema, systemd e seu recurso nativo para permitir sistemas de arquivos / tmp privados podem ser de interesse.

    
por 03.11.2012 / 19:10
0

para uma GUI tente isto; link

limpa e esfrega. modo de pré-visualização.

    
por 03.11.2012 / 20:12
0

Obtenha uma lista de arquivos mais antigos, exclua os arquivos que estão abertos por qualquer coisa dessa lista:

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

lsof -n +D /tmp : procure arquivos abertos em / tmp
awk 'NR>1 {print $9}' : imprima apenas a nona coluna de saída lsof, excluindo os cabeçalhos | tr \n \| : substitua nova-linha por barra (OR em egrep ) egrep -v "foo|moo|bar" : linhas de impressão que NÃO contêm foo ou moo ou bar

    
por 05.11.2012 / 13:02
0

Concordo com o acima, para adicionar-lhe embora- Eu sempre executo lsof +L1 | grep tmp e ou mato ou reinicio os processos que mantêm arquivos tmp "excluídos": EXEMPLO -

# 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)
    
por 02.09.2014 / 23:55
0

Você pode fazer rm -rf /tmp/* e esperar que nada quebre ...

    
por 03.07.2018 / 20:33