0

I am using python to run tcpdump to capture some probe requests from my phone. Right now, I am just printing it to the console.

def dumpNexus(self):
        proc = subprocess.Popen(["sudo", "tcpdump", "-i", "mon.wlan0", "-e", "-s", "0", "type", "mgt", "subtype", "probe-req", "and", "ether host", "bc:f5:ac:f2:xx:xx"], stdout=subprocess.PIPE,)
        for line in iter(proc.stdout.readline,''):
            print proc.stdout.readline()

My problem is that when I run this program, it won't print all of the lines that are being written by tcpdump.
If I run the tcpdump command and compare its output the the python program, the python program has significantly fewer packets displayed.

tcpdump will state that it captured 28 packets but only 11 are outputted through the subprocess stdout.

Any ideas why this is happening?

thanks

Anthony Pham
  • 3,096
  • 5
  • 29
  • 38

2 Answers2

3

The problem is you're calling readline() twice. First time inside of iter and then inside of the loop and so you end up ignoring the line returned by iter. A fix will be:

for line in iter(proc.stdout.readline, ''):
    print line

Or you can simply do:

for line in proc.stdout:
    print line
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • Ok yep, that was definitely an issue. Thank you – user2413192 Jan 14 '15 at 02:48
  • @user2413192: to avoid doubling all newlines, add comma at the end of the print statement (`sys.stdout.softspace` hack): `print line,` (<-- comma). `for line in proc.stdout` would delay output due to [hidden read-ahead bug on Python 2](http://bugs.python.org/issue3907), use `iter(proc.stdout.readline, b'')` instead. See [Python: read streaming input from subprocess.communicate()](http://stackoverflow.com/a/17698359/4279). – jfs Jan 14 '15 at 11:42
1

I believe that for something like this you want tcpdump to be in the "line buffered mode" - use the -l flag.

AMADANON Inc.
  • 5,753
  • 21
  • 31