Se um processo ativo tiver o arquivo aberto (não é incomum para arquivos de log), remover o arquivo e criar um novo não afetará o programa de registro; essas mensagens continuarão indo para o arquivo que não está mais vinculado . O esvaziamento do arquivo não interrompe a associação e, portanto, limpa o arquivo sem afetar o programa de registro.
( ênfase minha )
Não entendo por que um programa continuará registrando em um arquivo excluído. É porque a entrada do descritor de arquivo não foi removida da tabela de processos?
Ao excluir um arquivo, você realmente remove um link para o arquivo (para o inode). Se alguém já tiver esse arquivo aberto, ele manterá o descritor de arquivo que possui. O arquivo permanece no disco, ocupando espaço, e pode ser gravado e lido se você tiver acesso a ele.
A unlinkfunção é definida com este comportamento pelo POSIX:
Quando a contagem de links do arquivo se tornar 0 e nenhum processo tiver aberto o arquivo, o espaço ocupado pelo arquivo será liberado e o arquivo não estará mais acessível. Se um ou mais processos tiverem o arquivo aberto quando o último link for removido, o link será removido antes do retorno de unlink (), mas a remoção do conteúdo do arquivo será adiada até que todas as referências ao arquivo sejam fechadas .
Este conselho por causa desse comportamento. O daemon terá o arquivo aberto e não notará que ele foi excluído (a menos que o estivesse monitorando especificamente, o que é incomum). Ele continuará gravando alegremente o descritor de arquivo existente: você continuará ocupando (mais) espaço no disco, mas não poderá ver nenhuma das mensagens gravadas; portanto, você está realmente no pior dos dois mundos. Se você truncar o arquivo com tamanho zero, o espaço será liberado imediatamente e quaisquer novas mensagens serão anexadas no novo final do arquivo, onde você poderá vê-las.
Eventualmente, quando o daemon finalizar ou for closeo arquivo , o espaço será liberado. Entretanto, ninguém novo pode abrir o arquivo (exceto por meio de interfaces reflexivas específicas do sistema, como as do Linux/proc/x/fd/... ). Também é garantido que:
Se a contagem de links do arquivo for 0, quando todos os descritores de arquivos associados ao arquivo forem fechados, o espaço ocupado pelo arquivo será liberado e o arquivo não estará mais acessível.
Portanto, você não perde seu espaço em disco permanentemente, mas não ganha nada ao excluir o arquivo e perde acesso a novas mensagens.
O que ocorrerá se um usuário (digamos root aqui) tentar desvincular /proc/x/fd/y? Isso faria com que o processo falhasse ao gravar no descritor de arquivo ou é uma operação ilegal?
Nanofarad
@hexafraction /proc/*/fd/*são links simbólicos para arquivos reais, portanto, removê-los não excluirá o arquivo. Eu sugiro que você experimente :) (não no sistema de produção, é claro!)
Ruslan
1
@MichaelHomer Talvez você possa esclarecer em sua resposta que, uma vez que um arquivo é desvinculado, o processo com um descritor de arquivo apontando para ele pode vinculá-lo novamente, no mesmo caminho ou não. Às vezes, isso pode ser útil.
Lgeorget
@hexafraction Bem, essas são apenas representações (no espaço do sistema de arquivos) do estado do processo e dos objetos. Se você remover essas representações no espaço do sistema de arquivos, nada deverá acontecer com o processo real - a menos que ele (ou algum outro processo) dependa da representação existente. Não tenho certeza se você pode usá-lo rmincontinentemente dentro /procou /syssem ser avisado pelo sistema de qualquer maneira.
David Tonhofer
@lgeorget Como isso é realizado?
Michael
8
Exatamente.
Os arquivos são divididos em três partes.
O conteúdo, ou seja, uma matriz plana de bytes, gravada em algum lugar do disco ou gerada on-the-fly.
O nó de índice , ou inode, para abreviar, que é uma estrutura de dados preenchida e usada pelo kernel. Ele contém todos os metadados (tamanho, permissão, etc.) sobre o arquivo e também ponteiros para o local do conteúdo do arquivo.
Uma ou mais entradas de diretório , que são locais, manipulados como caminhos como /home/user/personal_file, que agem como alças através do qual você pode usar o arquivo, modificar seu conteúdo, alterar seus metadados, etc.
Ao abrir um arquivo, você indica o caminho para o sistema operacional e ele retorna um identificador diretamente para o inode. Com esse identificador, chamado de descritor de arquivo, você pode manipular o arquivo como desejar (ou pelo menos conforme permitido pelo sistema operacional).
Você nunca pode excluir diretamente um inode, é necessário fornecer um caminho para o sistema operacional para exigir a exclusão. Portanto, quando você deseja excluir um arquivo, exclua apenas a entrada do diretório. Se o arquivo tiver outras entradas de diretório, ele continuará acessível, e mesmo se não tiver, seu inode não será excluído enquanto ainda houver descritores de arquivo apontando para ele. A resposta do @ MichaelHomer é mais técnica e mais detalhada sobre esse tópico específico.
As outras 2 respostas explicam bem o problema - um arquivo não é "excluído" até que todos os links de diretório e todos os descritores de arquivos abertos acabem.
Para evitar isso, é um bom hábito usar
> /var/log/bigfile
ao invés de
rm -f /var/log/bigfile
pois isso redefine o conteúdo para 0 bytes, em vez de excluí-lo, e você ainda pode ver o que está escrito nele.
Se você excluiu o arquivo e está no linux em que possui um sistema de arquivos / proc / fd, ainda pode usar
> /proc/12345/fd/3
para zerar o conteúdo do arquivo (assumindo que 12345 é o seu ID de processo e 3 é o número fd do arquivo grande). Isso pode salvar vidas se o disco estiver cheio e você não conseguir interromper o processo que está gravando o arquivo de log por algum motivo.
> /var/log/bigfileremove os dados existentes no arquivo, mas não impede que programas sejam gravados lá. Existem muito poucas circunstâncias em que é a coisa certa. Eu diria que é um mau hábito entrar. Se você deseja excluir um arquivo, use rm. Se você deseja interromper os programas que estão gravando lá, mate-os ou faça-os parar de gravar, antes ou depois da exclusão.
Gilles 'SO- stop be evil'
1
@ Giles, este tópico é sobre o fato de que a exclusão não ajudará se um programa ainda tiver o arquivo aberto. E se o seu disco está cheio porque alguns misbehaves programa e syslogdpreenchimentos /var/log/messages, > /var/log/messagesé um muito melhor opção do que matar syslogd. Obviamente, isso não deve impedir você de analisar qual é o problema.
/proc/x/fd/y
? Isso faria com que o processo falhasse ao gravar no descritor de arquivo ou é uma operação ilegal?/proc/*/fd/*
são links simbólicos para arquivos reais, portanto, removê-los não excluirá o arquivo. Eu sugiro que você experimente :) (não no sistema de produção, é claro!)rm
incontinentemente dentro/proc
ou/sys
sem ser avisado pelo sistema de qualquer maneira.Exatamente.
Os arquivos são divididos em três partes.
/home/user/personal_file
, que agem como alças através do qual você pode usar o arquivo, modificar seu conteúdo, alterar seus metadados, etc.Ao abrir um arquivo, você indica o caminho para o sistema operacional e ele retorna um identificador diretamente para o inode. Com esse identificador, chamado de descritor de arquivo, você pode manipular o arquivo como desejar (ou pelo menos conforme permitido pelo sistema operacional).
Você nunca pode excluir diretamente um inode, é necessário fornecer um caminho para o sistema operacional para exigir a exclusão. Portanto, quando você deseja excluir um arquivo, exclua apenas a entrada do diretório. Se o arquivo tiver outras entradas de diretório, ele continuará acessível, e mesmo se não tiver, seu inode não será excluído enquanto ainda houver descritores de arquivo apontando para ele. A resposta do @ MichaelHomer é mais técnica e mais detalhada sobre esse tópico específico.
fonte
As outras 2 respostas explicam bem o problema - um arquivo não é "excluído" até que todos os links de diretório e todos os descritores de arquivos abertos acabem.
Para evitar isso, é um bom hábito usar
ao invés de
pois isso redefine o conteúdo para 0 bytes, em vez de excluí-lo, e você ainda pode ver o que está escrito nele.
Se você excluiu o arquivo e está no linux em que possui um sistema de arquivos / proc / fd, ainda pode usar
para zerar o conteúdo do arquivo (assumindo que 12345 é o seu ID de processo e 3 é o número fd do arquivo grande). Isso pode salvar vidas se o disco estiver cheio e você não conseguir interromper o processo que está gravando o arquivo de log por algum motivo.
fonte
> /var/log/bigfile
remove os dados existentes no arquivo, mas não impede que programas sejam gravados lá. Existem muito poucas circunstâncias em que é a coisa certa. Eu diria que é um mau hábito entrar. Se você deseja excluir um arquivo, userm
. Se você deseja interromper os programas que estão gravando lá, mate-os ou faça-os parar de gravar, antes ou depois da exclusão.syslogd
preenchimentos/var/log/messages
,> /var/log/messages
é um muito melhor opção do que matarsyslogd
. Obviamente, isso não deve impedir você de analisar qual é o problema.