Bash: how to make a replacement in a live pipe?

In my office firewall, I use the following command:

$ sudo tcpdump -v -s 1500 -i eth0 port 25 | grep 'smtp: S'

for monitoring LAN clients sending mail (I need to detect any possible spam bot from some client in advance, we have a very looooose security policy, here ...: - ().

So far so good: I have a continuous exit as soon as any client sends an email.

But if I add a filter to get a cleaner result, something like this:

$ sudo tcpdump -v -s 1500 -i eth0 port 25 | grep 'smtp: S' | perl -pe 's/(.*?\)) (.*?)\.\d+ \>(.*)/$2/'

(here I intend to get only the source ip / name), I don't get any output until the tcpdump output is larger (bash?) the size of the buffer ... (or at least I suppose so).

Nothing changes using "sed" instead of "perl" ...

Any hint on getting continuous output of filtered data?

+4
source share
3 answers

Place stdbufbefore the first command:

sudo stdbuf -o0 tcpdump ...
+4
source

But, if I add a filter to get a cleaner result, something like this:

Use the parameter --line-bufferedfor grep:

   --line-buffered
          Use  line  buffering  on  output.   This can cause a performance
          penalty.
+2
source

perhaps try sed --unbuffered(or -u, sometimes like on AIX) to have a strom version (without waiting for EOF)

0
source

All Articles