Esvazie um arquivo sem que o grep o trate posteriormente como um arquivo binário

Esvazie um arquivo sem que o grep o trate posteriormente como um arquivo binário

Atualmente tenho netcatuma saída de tubulação teeque está gravando em output.txt com

nc -l -k -p 9100 | tee output.txt

Quero monitorar essa saída, então estou assistindo tail -f | egrep -i 'regex'via PuTTY para ver apenas os bits relevantes.

De vez em quando quero limpar o arquivo de saída. Surge a questão de que, se eu fizer isso > output.txte tentar novamente, tail -f | egrep ...não obtenho saída. Se eu vasculhar o arquivo, não recebo correspondências, apesar de saber que hádeveser correspondências (como cat output.txtcospe o arquivo corretamente)

mitch@quartz:~$ grep output.txt -e 'regex'
Binary file output.txt matches

Embora o mesmo comando em output.txtantesesvaziá-lo funciona bem.

Basicamente: >faz greppensar que meu arquivo é um arquivo binário e não será pesquisado corretamente. Existe uma maneira melhor de limpar o arquivo?

Responder1

Se o único problema é que grepo trata como binário, diga greppara pesquisá-lo independentemente:

$ head /bin/bash > out
$ echo "test" >> out 
$ grep test out 
Binary file out matches
$ grep -a test out 
test

De man grep:

   -a, --text
          Process  a binary file as if it were text; this is equivalent to
          the --binary-files=text option.

Responder2

Isso pode responder à sua pergunta, então aqui estão os resultados de alguns testes que acabei de executar:

$ > output.txt
$ file output.txt
output.txt: empty

$ echo "" > output.txt
$ file output.txt
output.txt: very short file (no magic)

$ echo " " > output.txt
$ file output.txt
output.txt : ASCII text

Como você pode ver, o arquivo não é categorizado da mesma forma de acordo com o que você realmente"colocar" quando você tentar limpá-lo. Portanto, você pode querer usar uma string vazia em vez de simplesmente nada.

Responder3

>faz o grep pensar que o arquivo é binário porque é binário. Acontece que você esvaziou o arquivo, mas não interrompeu o programa que o estava preenchendo.

>output.txtcria output.txtse não existir e trunca-o para comprimento zero se existir.

No ponto em que você executa >output.txt, há um teeprocesso que mantém o arquivo aberto. Truncar o arquivo não afeta a posição em que teeestá sendo gravado. Digamos que tenha escritoNbytes antes do truncamento. Na próxima vez que teeescrever após o truncamento, ele começará a escrever na posiçãoN. É permitido escrever em uma posição além do final atual de um arquivo e preencher o início do arquivo com bytes nulos.¹ Foi o que aconteceu aqui.

Grep vê um arquivo que começa com alguns bytes nulos. Ele relata corretamente o arquivo como binário.

Você pode dizer ao GNU grep para tratar o arquivo como texto chamando grep -a. Ele pesquisará todo o arquivo, incluindo os bytes nulos (que não correspondem, portanto não afetam o resultado, a menos que haja uma correspondência na primeira linha, mas podem causar lentidão se houver muitos deles).

Uma solução melhor é dizer teepara escrever sempre no final atual do arquivo. Felizmente (comoStéphane Chazelas comentou), existe uma opção para isso: tee -a(presente em todos os sistemas compatíveis com POSIX). Você precisará truncar o arquivo primeiro.

>output.txt
nc -l -k -p 9100 | tee -a output.txt

¹ A maioria dos sistemas de arquivos permite que blocos que consistiriam inteiramente de bytes nulos permaneçam não alocados. Este método especializado de compressão é chamado de fazer umarquivo esparso.

informação relacionada