
Noto que cuando lo uso tcpdump
para leer un archivo pcap, el tcpdump
comando de alguna manera logra imprimir información en mi consola incluso cuando redirijo tanto STDOUT como STDERR. ¿Cómo puedo evitar tcpdump
imprimir " reading from file capture, link type EN10MB (Ethernet)
" cada vez que se ejecuta?
Por ejemplo, el siguiente comando imprime una línea cuando no esperaba ninguna:
$ tcpdump -A -r capture.pcap | grep interesting-string > /dev/null 2>&1
reading from file capture.pcap, link-type EN10MB (Ethernet)
Me gustaría evitar que aparezca esa línea porque agrega ruido innecesario y no deseado a la salida de un script. Revisé la página de manual y no vi una opción para evitar que aparezca ese mensaje. Busqué en la web formas de suprimir la salida no capturada por STDOUT y STDERR, y encontré algunos resultados, pero ninguno que pudiera entender o usar en este contexto.
Respuesta1
Creo que desea colocar la redirección de salida antes de la tubería, para que se aplique a la salida de tcpdump, no a la de grep.
tcpdump -A -r capture.pcap 2>&1 | grep interesting-string > /dev/null
Respuesta2
Una versión más detallada de la respuesta de Spiff:
Si tienes una tubería
command1 | command2
luego ordene la salida estándar de 1, peronosu error estándar, se redirige a una tubería que va a la entrada estándar del comando 2.
Así que si lo haces
command1 | command2 >/dev/null 2>&1
que envía la salida estándar del comando 2 a /dev/null
y envía el error estándar al mismo lugar donde se envió la salida estándar (para que también vaya /dev/null
en este caso), pero no hace nada con el error estándar del comando 1 y deja la salida estándar del comando 1 canalizada a la entrada estándar del comando 2.
Sin embargo, el comando
command1 2>/dev/null | command2 >/dev/null 2>&1
enviará la salida estándar del comando 1 a la entrada estándar del comando 2, el error estándar del comando 1 a /dev/null
y la salida estándar y el error del comando 2 a /dev/null
y el comando
command1 2>&1 | command2 >/dev/null 2>&1
enviará la salida estándar del comando 1 a la entrada estándar del comando 2, el error estándar del comando 1 al mismo lugar que la salida estándar del comando 1 - es decir, a la entrada estándar del comando 2 - y enviará la salida estándar y error del comando 2 a /dev/null
.
Así por ejemplo
tcpdump -A -r capture.pcap 2>&1 | grep interesting-string > /dev/null 2>&1
hará grep
que se vean tanto la salida estándar como el error de tcpdump
(por lo que verá el reading from file...
mensaje y lo comparará si la cadena interesante es parte de él) y enviará la salida estándar y el error de grep
a /dev/null
, por lo que no debería producircualquiersalida, debería simplemente dar el estado de salida grep
(que supongo que es su intención, es decir, todo lo que quiere saber es si la cadena interesante es parte de alguno de los paquetes).
Por cierto, si está utilizando grep
para averiguar si una cadena determinada es parte de su entrada o no, y no desea ninguna salida, intente usarla grep -q
si su versión grep
lo admite; eso correrá más rápido, porque
grep
no tiene que gastar tiempo de CPU escribiendo en/dev/null
;grep
podría cerrarse tan pronto como vea la cadena, por lo que no gastará más tiempo de CPU leyendo, y tcpdump morirá con un error de "tubería cerrada" después degrep
salir yélno gastará más tiempo de CPU o ancho de banda de disco/SSD leyendo el archivo.
(Las versiones anteriores de grep
se usaban -s
para el mismo propósito, pero el estándar UNIX dice que es -q
, y la mayoría de los sistemas UNIX y similares lo hacen ahora; GNU grep
, por ejemplo, usa -q
.)