Esvazie um arquivo sem grep tratando-o posteriormente como um arquivo binário

6

Atualmente, tenho netcat saída de tubulação para tee que está gravando para output.txt com

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

Eu quero monitorar esta saída, então eu estou assistindo com tail -f | egrep -i 'regex' via PuTTY para que eu veja apenas bits relevantes.

De vez em quando eu quero limpar o arquivo de saída. Surge a questão de que, se eu fizer > output.txt e, em seguida, tentar novamente tail -f | egrep ... , não receberei saída. Se eu percorrer o arquivo, não obtenho nenhuma correspondência, apesar de saber que deve ser correspondências (como cat output.txt exibe o arquivo corretamente)

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

Enquanto o mesmo comando no output.txt anterior esvazia, funciona bem.

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

    
por Mitch 15.10.2014 / 15:42

3 respostas

5

Se o único problema é que grep o trata como binário, informe grep para procurá-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.
    
por 15.10.2014 / 15:56
3

Ele 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 maneira, de acordo com o que você realmente "coloca " nele quando você tenta limpá-lo. Portanto, você pode querer usar uma string vazia em vez de apenas nada.

    
por 15.10.2014 / 15:48
3

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

>output.txt cria output.txt , se não existir, e trunca para zero, se o fizer.

No ponto em que você executa >output.txt , há um processo tee que tem o arquivo aberto. Truncar o arquivo não afeta a posição na qual tee está escrevendo. Digamos que ele tenha escrito N bytes antes do truncamento. Na próxima vez que tee escrever após o truncamento, ele começará a gravar na posição N . Escrever em uma posição além do final atual de um arquivo é permitido e preenche o início do arquivo com bytes nulos.¹ Foi o que aconteceu aqui.

O 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 irá procurar o arquivo inteiro, incluindo os bytes nulos (que não correspondem, para que eles não afetem o resultado, a menos que haja uma correspondência na primeira linha, mas eles podem causar lentidão se houver muitos deles).

Uma solução melhor é informar tee para sempre gravar no final atual do arquivo. Felizmente (como Stephane Chazelas comentou , há 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 consistam inteiramente de bytes nulos permaneçam não alocados. Esse método especializado de compactação é chamado de criação de um arquivo esparso .

    
por 16.10.2014 / 02:04