Como esvaziar (“truncar”) um arquivo no linux que já existe e está protegido de alguma forma?

113

Tenho um arquivo chamado error.log em meu servidor que preciso truncar com frequência. Eu tenho permissões rw para o arquivo. Abrir o arquivo no vi> deletar todo o conteúdo> salvar funciona (obviamente). Mas quando eu tento o abaixo

cat /dev/null > error.log

Eu entendi a mensagem

File already exists.

Obviamente, há algum tipo de configuração feita no servidor para evitar a substituição acidental de arquivos. Alguém pode dizer como faço para "truncar" o arquivo em um único comando?

Sumeet Pareek
fonte
2
Para um arquivo não protegido, truncar -s 0 arquivo funciona.
Pramod

Respostas:

158

Você tem a noclobberopção definida. O erro parece ser de csh, então você deve fazer:

cat /dev/null >! file

Se eu estiver errado e você estiver usando o bash, faça o seguinte:

cat /dev/null >| file

no bash, você também pode encurtar para:

>| file
R Samuel Klatchko
fonte
você está certo sobre o shell ser csh. Como você sabia disso?
Sumeet Pareek
6
@Wikidkaka - com base na mensagem de erro. csh no meu sistema dá um File existserro semelhante, enquanto bash dá um cannot overwrite existing fileerro muito diferente .
R Samuel Klatchko
6
@Jarmund - porque o usuário tem noclobber definido, >filenão funciona.
R Samuel Klatchko
Qual é a diferença entre > filee >| file?
Será
1
@Will - se você tiver a noclobberopção definida, tentar redirecionar para um arquivo existente falhará. Para substituir o redirecionamento específico enquanto deixa o noclobber ativado, você pode usar>|
R Samuel Klatchko
71

Você também pode usar a função truncate

$truncate -s0 yourfile

se a permissão for negada, use sudo

$sudo truncate -s0 yourfile

Ajuda / manual: homem truncado

testado em ubuntu Linux

Risnandar
fonte
1
truncar também toca na hora de modificação do arquivo - enquanto "> arquivo" não toca se o arquivo não foi alterado.
dsteinkopf
Ele não libera o espaço em disco que o arquivo contém. A princípio mostra os 0 bytes. Mas quando você grava algo nesse arquivo, o tamanho do arquivo é = antes de truncar + novo tamanho de dados.
Aniket Kulkarni
48

Isso será o suficiente para definir o tamanho do arquivo como 0:

> error.log
SIFE
fonte
6
na verdade, isso não funciona com noclobber (testei sozinho), então NÃO é uma solução válida neste caso ("-bash: error.log: não é possível sobrescrever o arquivo existente"); veja o elogio acima ("@Jarmund - porque o usuário configurou noclobber,> o arquivo não funciona."). Só estou me perguntando que tipo de "pessoas inteligentes"
9

o crédito vai para meu colega sênior por isso:

:> filename

Isso não vai quebrar os arquivos de log, então você pode até mesmo usá-lo no syslog, por exemplo.

Petermolnar
fonte
8
Por favor explique. Como funciona? O que essa notação está fazendo?
user31986 de
2
@ user31986 :é um comando sem efeito (quase um comentário), então >é um redirecionamento como de costume, portanto, apenas redireciona a falta de saída de um comando que não faz nada no arquivo. Se noclobber estiver habilitado, você precisa :>| filename(bash) (e presumo :>! filenameem csh assumindo que csh tem :).
Ruibarbo
4

false | tee fileToTruncate

pode funcionar bem

Dodger Web
fonte
Isso é bobagem. Ou, se isso for útil, obter de forma obscura dda saída de nada seria ainda melhor do que a leitura simples false?
tripleee
2

Como o sudo não funciona com redirecionamento > , gosto do teecomando para esse propósito

echo "" | sudo tee fileName
Sakhunzai
fonte
bem, na verdade é, conforme descrito na pergunta que você vinculou e aqui acima. "sudo sh -c '> error.log'" ...
depende das permissões no arquivo de destino error.log, se ele já for gravável, não há necessidade de sudo. Acho que o outro problema é que você está passando o comando como um argumento de string para sh, não sei como isso é tratado internamente, mas essa é outra camada de complexidade / redirecionamento adicionada
sakhunzai
1
Isso não truncará o arquivo, porque echo ""adicionará uma nova linha. Você pode usar echo -n ""para suprimir a nova linha
Seb
0

Qualquer um pode tentar este comando para truncar qualquer arquivo no sistema linux

Isso certamente funcionará em qualquer formato:

truncate -s 0 file.txt
user3301460
fonte
0

Eu gosto disso: cp /dev/null file

Den129
fonte
-4

Você também pode tentar:

echo -n > /my/file

Oden
fonte
8
Veja a resposta com uma tonelada de votos? Tente lê-lo, olhe para cima noclobbere pergunte a si mesmo se sua resposta faz algum sentido.