Search code examples
bashunixawkpipetcpdump

Piping the output of tcpdump multiple times


In bash, usually you cannot send the output of tcpdump to an awk expression, as explained in this Stack Exchange question. This prints nothing:

sudo tcpdump -i en1 -n -q 'tcp[13]=18 and src port 80' | awk '{$0=$3; sub(".80$",""); print $0}'

The solution is to buffer the output with the -l flag, like this, which works as expected:

sudo tcpdump -i en1 -n -q -l 'tcp[13]=18 and src port 80' | awk '{$0=$3; sub(".80$",""); print $0}'

However, when I tried to pipe the output of the awk to a file or anywhere else, the file is created but stays empty, even if tcpdump says that it received packets.

sudo tcpdump -i en1 -n -q -l 'tcp[13]=18 and src port 80' | awk '{$0=$3; sub(".80$",""); print $0}' | tee -a file.txt

or

sudo tcpdump -i en1 -n -q -l 'tcp[13]=18 and src port 80' | awk '{$0=$3; sub(".80$",""); print $0}' | awk '{print $3}' >> file.txt

My workaround has been to output to a file, and then run the awk on the file later, exporting to another file, but this makes it impossible to read the edited file in realtime. Any ideas on why this happens?


Solution

  • awk has an fflush function that sends the output buffer:

    sudo tcpdump -i eth0 -q -l | awk '{print $3; fflush}' | tee -a file.txt