Script shell Unix para truncar um arquivo grande

87

Estou tentando escrever um script Unix que irá truncar / esvaziar um arquivo que está continuamente sendo escrito / aberto por um aplicativo quando atinge, digamos, 3 GB de espaço. Eu sei que o comando abaixo faria isso:

cp /dev/null [filename]

Mas vou executar isso em um ambiente de produção automaticamente como um cron job - apenas postando aqui para ver se vocês enfrentaram algum problema ao fazer algo semelhante a isso.

fazer xixi
fonte
Estes são prod. os logs não têm valor? Tive a sorte de manter meus registros de produção por mais de um ano (em bzip2 -9 fmt) e tinha alguns pequenos utilitários que tornavam fácil extrair tempos de execução de trabalho, registros processados ​​e quando carregados em uma planilha eram fáceis de calcular e gráficos de taxas de carregamento e um monte de coisas. Descobrimos um problema de hdwr devido à queda nas taxas de carga. Sim, existem ótimas ferramentas de monitoramento, então tudo depende da sua situação. COMO UMA OPÇÃO SEPARADA, você olhou logrotate, pode fornecer algum valor (mas ser chato com a configuração (apenas adivinhando)!).
shellter
5
Observe que, se o arquivo de log for aberto com o sinalizador O_APPEND, o truncamento será eficaz. Se não for aberto com o sinalizador O_APPEND, o programa continuará gravando no deslocamento de 3 GiB (a primeira vez); o sistema tratará os primeiros 3 GiB como todos bytes zero (o que é bem compactado), mas o arquivo continuará crescendo. Tudo depende do programa que está escrevendo o log.
Jonathan Leffler

Respostas:

116

Só para adicionar outra resposta,

: > filename

: é um ambiente autônomo no bash (compatível com POSIX), então isso basicamente abre o arquivo para gravação (o que obviamente trunca o arquivo) e o fecha imediatamente.

EDITAR: como comentou shellter, você não precisa de um comando para acompanhar o redirecionamento:

$ echo foo > foo.txt
$ cat foo.txt
foo
$ > foo.txt
$ cat foo.txt
$

Um simples redirecionamento por si só limpará o arquivo.

chepner
fonte
25
ou apenas > filename(como tenho certeza que você sabe). Boa sorte a todos.
shellter
5
@shelter "$> file" não POSIX e não portátil. Você deve usar o comando ":" no-op antes de redirecionar, conforme sugerido inicialmente.
Aaron Toponce
2
+ plus para rosto sorridente
Chris Suszyński
2
Como @AaronToponce apontou, "$> file" de fato não é portátil; na minha configuração Zsh, ele faz o shell travar (supostamente esperando por uma entrada). "$:> arquivo" funciona perfeitamente no Zsh.
Linus Arver
1
@TechEnthusiast Depende da sua expectativa. O truncamento em si é atômico, mas você não sabe realmente quando isso acontecerá em relação a qualquer gravação específica. Você poderia, por exemplo, terminar com uma linha parcial no início do arquivo.
chepner
65

Eu usei o seguinte comando no debian

truncate -s 0 filename
Ricardo Marimon
fonte
@SteveClay: sudo sh -c ': > filename'também filename
truncará
2
@SteveClay A sugestão PO também funciona perfeitamente com sudo: sudo cp /dev/null filename. Também cpé portátil, enquanto truncateo Linux moderno é apenas.
Tino
11

Isso me parece razoável. O Unix, é claro, permite que você faça isso de cerca de 50 maneiras diferentes. Por exemplo,

echo -n "" >filename
cat /dev/null >filename
Don Branson
fonte
2

trunc filename

funciona no tipo AIX do UNIX

San
fonte