Search code examples
bashperlshelldiamond-operator

Unable to redirect output of a perl script to a file


Even though the question sounds annoyingly silly, I am stuck with this. The described issue occurs on both Ubuntu 14.04 and CentOS 6.3.

I am using a perl script called netbps as posted in the answer (by RedGrittyBrick): https://superuser.com/questions/356907/how-to-get-real-time-network-statistics-in-linux-with-kb-mb-bytes-format-and-for

The above script basically takes the output of tcpdump (a command whose details we don't need to know here) and represents it in a different format. Note that the script does this in streaming mode (i.e., the output is produced on the fly).

Hence, my command looks like this:

tcpdump -i eth0 -l -e -n "src portrange 22-233333 or dst portrange 22-23333" 2>&1 | ./netbps.prl

And the output produced on the shell/console looks like this:

13:52:09      47.86 Bps
13:52:20     517.54 Bps
13:52:30     222.59 Bps
13:52:41    4111.77 Bps

I am trying to capture this output to a file, however, I am unable to do so. I have tried the following:

  1. Redirect to file:

tcpdump -i eth0 -l -e -n "src portrange 22-233333 or dst portrange 22-23333" 2>&1 | ./netbps.prl > out.out 2>&1

This creates an empty out.out file. No output appears on the shell/console.

  1. Pipe and grep:

tcpdump -i eth0 -l -e -n "src portrange 22-233333 or dst portrange 22-23333" 2>&1 | ./netbps.prl 2>&1 | grep "Bps"

No output appears on the shell/console.

I don't know much about perl, but this seems to me like a buffering issue -- not sure though? Any help will be appreciated.


Solution

  • It is a buffering problem. Add the line STDOUT->autoflush(1) to netbps and it will work.

    STDOUT is normally line buffered, so the newline on the end of printf should trigger a buffer flush, but because it's redirected to a file it is buffered like any normal file. You can see this with...

    $ perl -e 'while(1) { print "foo\n"; sleep 5; }'
    

    vs

    $ perl -e 'while(1) { print "foo\n"; sleep 5; }' > test.out