No passado, em sistemas linux, eu era capaz de truncar arquivos de log grandes e abertos (ou seja, um arquivo que está sendo gravado ativamente por um processo) usando cat /dev/null > file.log
.
No entanto, no 10.9 (Mavericks), esse não parece ser o caso. Eu tenho um arquivo de 11 GB que está sendo registrado por um aplicativo, mas quando executo o mesmo comando com esse arquivo, nada parece acontecer.
Quando eu tento isso em um arquivo de tamanho trivial, ele funciona.
Aqui está ls -l /dev/null
:
crw-rw-rw- 1 root wheel 3, 2 Dec 16 12:49 /dev/null
Eu também tentei cp /dev/null file.log
sem sucesso.
Pensando que eu poderia tirar proveito da função truncada ( man 2 truncate
em Darwin), compilei isso e executei-o em dois arquivos, um de tamanho trivial e outro no arquivo de log real. Novamente, funcionou contra o arquivo trivial e não funcionou no log muito maior.
/*
* Copyright (c) 2013 Thomas de Grivel <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
...
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <unistd.h>
int main (int argc, const char **argv)
{
int e = 0;
while (--argc) {
argv++;
if (truncate(*argv, 0)) {
e = 4;
warn("%s", *argv);
}
}
return e;
}
O processo retorna 0
independentemente de qual arquivo eu uso.
du
oudu -h
diz? É possível que o arquivo seja um arquivo esparso?du -h /tmp/file.log
resultados em11G /tmp/file.log
Respostas:
cat /dev/null
é um pouco complicado uma maneira de escrever um comando que não produz saída.:
outrue
são mais óbvias.Em todos
cat /dev/null > file
,: > file
e até mesmo> file
na maioria das conchas, o shell abre arquivo com O_TRUNC em stdout, em seguida, executa o aplicativo que não faz nada de saída, em seguida, o arquivo é fechado e deixou truncado.No entanto, nesse caso ou ao usar a
truncate
chamada do sistema, se o processo que está preenchendo esse arquivo não o abriu com o sinalizador O_APPEND, na próxima vez em que ele gravar no descritor de arquivo aberto no arquivo, ele gravará os dados no deslocamento estavam dentro do arquivo.Como o HFS + não suporta arquivos esparsos, isso significa que o espaço antes desse deslocamento precisará ser realocado e preenchido com zeros pelo sistema.
Portanto, você precisa matar o aplicativo que está gravando nesse arquivo antes de truncá-lo. Ou você precisa garantir que o aplicativo abra o arquivo
O_APPEND
(como no>>
caso de usar o redirecionamento de shell).Se você quiser experimentar:
Agora, o fd 3 do meu shell tem 100000 bytes no arquivo
Agora o arquivo está truncado (tamanho 0, sem espaço usado no disco).
Gravando 1 byte no arquivo no deslocamento 100000, o arquivo agora tem 100001 bytes de tamanho, os primeiros zeros, usariam mais de 100k no HFS +, mas apenas um bloco de disco na maioria dos outros sistemas de arquivos Unix
Por outro lado, com:
A gravação de 1 byte no arquivo não está no deslocamento 100000, mas no final do arquivo por causa de
O_APPEND
. O arquivo tem 1 byte de tamanho e ocupa o espaço necessário para armazenar esse byte.fonte