Esvaziando o conteúdo de um arquivo de texto

16

Eu tenho um arquivo de texto no meu diretório pessoal que recebe dados regularmente através de um trabalho cron. Como o trabalho cron fornece dados dinâmicos, eu também gostaria de definir um trabalho cron para esvaziar o conteúdo do arquivo (o arquivo ainda deve existir). Não preciso de ajuda com o cron, apenas o comando que pode ajudar no esvaziamento do arquivo.

sosytee
fonte
5
Alternativa: tail -n +1000 file.txt > file.txtremova 1000 linhas e mantenha as linhas mais recentes no arquivo (você nunca sabe quando poderá precisar de parte do registro recente para rastrear algo).
Rinzwind 12/09
2
Essa é realmente uma opção melhor do que limpar o arquivo em horários agendados.
Bruno Pereira
1
@Rinzwind, isso não funcionará, já que o arquivo será truncado antes que o tail tente lê-lo. Você precisa redirecionar para um novo arquivo e substituir o original pelo novo.
Psusi 12/09/2013
Verdadeiro @psusi :) é necessário que haja um redirecionamento extra lá.
Rinzwind 12/09

Respostas:

28

A maneira mais simples:

> filename

Essa é uma maneira menos óbvia e provavelmente menos legível em outros scripts de shell, mas é tudo que você precisa.

Porque >na verdade não é realmente um comando (é bash embutido), você não pode usar:

sudo > filename

quando você não tem permissões nesse arquivo. Mas você pode usar:

sudo bash -c "> filename"
Radu Rădeanu
fonte
que tipo de permissões precisam ser alteradas porque ele diz permissão negada, eu tenho feito chmod 755 para o arquivo já, ou eu deveria torná-lo um novo Post (i significa a questão permissões)
sosytee
@sosytee Veja minhas novas edições.
Radu Rădeanu
1
@sosytee Claro que você pode, mas use sudo crontab -epara adicionar o cron job para root, não para você. Ou alterar a permissão do arquivo para 766 (ou 666), não 755: sudo chmod 766 filename. Mais sobre: codex.wordpress.org/Changing_File_Permissions
Radu Rădeanu
1
truncate filenameé um pouco mais limpo e mais simples do que redirecionar a saída vazia para o arquivo e não se depara com problemas sudo.
Psusi
1
@psusi truncate -s 0 filenamerealmente pode fazer o truque. Você pode adicioná-lo como resposta.
Radu Rădeanu
19

Existe uma ferramenta criada para esse fim:

truncate -s 0 filename

Isso limpará o conteúdo, mas continuará sendo o mesmo arquivo (o inode permanece o mesmo).

Isso é importante porque alguns programas mantêm um identificador para o arquivo "by inode". Suponha que você "esvazie" um arquivo usando o método ingênuo de excluir e recriar o arquivo. Alguns programas ainda podem manter um identificador para o arquivo antigo (com o conteúdo antigo), mesmo que ele não esteja mais visível, como os meios usuais ls.

Alguns links para mais detalhes no final desta resposta.


Outra maneira, talvez mais fácil de lembrar:

echo -n > filename

Isso também mantém o mesmo inode.

Observe que ambos truncatee echo -nnão são definidos pelo POSIX .

Para uso em conformidade com POSIX cat /dev/null:

cat /dev/null > filename

Ainda outra maneira, mais obscura e provavelmente não agnóstica:

> filename

Se o arquivo a truncar precisar de privilégios de root para gravar, as seguintes linhas não funcionarão como o esperado:

sudo echo -n > filename
sudo cat /dev/null > filename
sudo > filename

Isso ocorre porque o redirecionamento é feito pelo shell antes mesmo de o sudo ser executado. Isso significa que o acesso de gravação ao arquivo é feito usando os privilégios do usuário que executa o shell, não os privilégios que serão concedidos pelo sudo.

Uma solução alternativa é adiar o redirecionamento para um shell executado usando privilégios sudo como este:

sudo sh -c "echo -n > filename"

truncateVocê não precisa usar essa solução alternativa, porque o acesso de gravação não é feito pelo shell, mas pelo truncatequal é executado pelo sudo usando privilégios de sudo.

sudo truncate -s 0 filename

Para obter alguns detalhes sangrentos sobre programas que mantêm o arquivo aberto, mesmo que o arquivo tenha sido excluído, você pode ler o seguinte:

lesmana
fonte
ele diz Permissão negada, usaram chmod 755 filename mas ainda a permissão é negada
sosytee
2
talvez você tenha o noclobber ativado no bash?
Lesmana
A resposta mais completa até o momento
AbdelHady
4

Para automatizar isso, você pode usar o logrotate. Basta criar um arquivo de configuração para o arquivo que você deseja esvaziar, adicionar outras configurações e deixá-lo vazio todos os dias automaticamente com base nos critérios que você escolher todos os dias ou quando o arquivo for maior que etc.

Veja aqui como configurar o logrotate: http://linuxcommand.org/man_pages/logrotate8.html

piotrektt
fonte
1
Eu sou a favor dessa opção. Usamos "arquivo> 10 Mb" -> "tar.gz para fazer backup" "do arquivo vazio". E os backups são excluídos após 900 dias.
Rinzwind 12/09
3

echo "" > foo_fileé uma maneira simples de fazer isso, ele substituirá todo o conteúdo do foo_file por "" tornando-o vazio.

Você também pode usar cat /dev/null > foo_file, que lerá o dispositivo nulo e substituirá seu arquivo sem nada.

Bruno Pereira
fonte
ele diz Permissão negada, usaram chmod 755 filename porém ainda a permissão for negada
sosytee
Você pode ler as permissões de arquivo com seu usuário normal, por favor?
Bruno Pereira
sim eu posso ler o conteúdo como usuário normal
sosytee