Eu acho que você quer colocar o redirecionamento de saída antes do pipe, para que ele se aplique à saída do tcpdump, não ao grep.
tcpdump -A -r capture.pcap 2>&1 | grep interesting-string > /dev/null
Noto que ao usar tcpdump
para ler um arquivo pcap, o comando tcpdump
de alguma forma consegue imprimir informações em meu console mesmo quando eu redireciono STDOUT e STDERR. Como posso evitar que tcpdump
imprima " reading from file capture, link type EN10MB (Ethernet)
" sempre que é executado?
Por exemplo, o seguinte comando imprime uma linha quando não esperava nenhum:
$ tcpdump -A -r capture.pcap | grep interesting-string > /dev/null 2>&1
reading from file capture.pcap, link-type EN10MB (Ethernet)
Eu gostaria de impedir que essa linha aparecesse porque adiciona ruído desnecessário e indesejado à saída de um script. Verifiquei a página do manual e não vi uma opção para impedir que essa mensagem aparecesse. Eu procurei na web por maneiras de suprimir a saída não capturada por STDOUT e STDERR, e encontrei alguns hits, mas nenhum que eu pudesse entender ou usar neste contexto.
Uma versão mais detalhada da resposta do Spiff:
Se você tem um pipeline
command1 | command2
então a saída padrão do comando 1, mas não seu erro padrão, é redirecionada para um pipe indo para a entrada padrão do comando 2.
Então, se você fizer
command1 | command2 >/dev/null 2>&1
que envia a saída padrão do comando 2 para /dev/null
e envia o erro padrão para o mesmo local em que a saída padrão foi enviada (para que também vá para /dev/null
neste caso), mas não faça qualquer coisa com o erro padrão do comando 1 e deixe a saída padrão do comando 1 canalizada para a entrada padrão do comando 2.
No entanto, o comando
command1 2>/dev/null | command2 >/dev/null 2>&1
enviará a saída padrão do comando 1 para a entrada padrão do comando 2, o erro padrão do comando 1 para /dev/null
e a saída padrão e o erro do comando 2 para /dev/null
e o comando
command1 2>&1 | command2 >/dev/null 2>&1
enviará a saída padrão do comando 1 para a entrada padrão do comando 2, o erro padrão do comando 1 para o mesmo local que a saída padrão do comando 1 - isto é, para a entrada padrão do comando 2 - e enviará a saída padrão e o erro do comando 2 para /dev/null
.
Então, por exemplo
tcpdump -A -r capture.pcap 2>&1 | grep interesting-string > /dev/null 2>&1
fará com que grep
veja a saída e o erro padrão de tcpdump
(assim, verá a mensagem reading from file...
e combine-a se a sequência interessante fizer parte dela) e enviará a saída padrão e erro de grep
to /dev/null
, então ele não deve produzir saída any , ele deve apenas dar o status de saída de grep
(o que eu presumo é sua intenção, ou seja, tudo que você quer saber é se a string interessante é parte de qualquer um dos pacotes).
BTW, se você estiver usando grep
para descobrir se uma determinada string faz parte de sua entrada ou não, e não quiser nenhuma saída, tente usar grep -q
se sua versão de grep
a suportar; que vai correr mais rápido, porque
grep
não precisa gastar o tempo de CPU escrevendo para /dev/null
; grep
pode encerrar assim que visualizar a string, então não gastará mais tempo lendo a CPU, e o tcpdump irá morrer com um erro de "Closed pipe" após grep
e it não gastará mais tempo de CPU ou leitura de largura de banda de disco / SSD do arquivo. (Versões antigas de grep
usaram -s
para o mesmo propósito, mas o padrão UNIX diz que é -q
, e a maioria dos sistemas UNIX e UNIX fazem isso agora; por exemplo, o GNU grep
-q
.)
Tags command-line stdout tcpdump linux stderr