Python subprocess: stderr only saving the first line. Why?
Question: I am running `tcpdump` from within **Python** and I would like to know how
many **packets** are **dropped by the kernel**.

When run on a command line, tcpdump looks like this:

    
    
    me@mypc:$ sudo tcpdump -w myPackets.cap -i eth0 ip
    tcpdump: listening on eth2, link-type EN10MB (Ethernet), capture size 65535 bytes
    ^C28 packets captured
    28 packets received by filter
    0 packets dropped by kernel
    

This is how I call `tcpdump` in my Python script:

    
    
    f_out = open("tcpdumpSTDOUT", "w")
    f_err = open("tcpdumpSTDERR", "w")
    tcpdumpProcess = subprocess.Popen(['tcpdump',
                            '-w', 'myPackets.cap', '-i', 'eth0', '-n','ip'],
                            stdout=f_out,
                            stderr=f_err)
    # a few seconds later:
    tcpdumpProcess.kill()
    f_in.close()
    f_out.close()
    

Now, if I look at `tcpdumpSTDERR`, I **only** see the **first of the usual
output lines** :

> tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535
> bytes

Where's all the rest?

**EDIT** I tried a different approach:

    
    
    >>> myProcess = subprocess.Popen("tcpdump -w myPackets.cap -i eth2 ip",  shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    >>> myProcess.communicate()
    

Then I killed tcpdump from a different shell, and the output of commnunicate()
was displayed:

    
    
    ('', 'tcpdump: listening on eth2, link-type EN10MB (Ethernet), capture size 65535 bytes\n')
    

... still the first line only!

**EDIT 2** Interestingly:

    
    
    >>> import shlex
    >>> a = subprocess.Popen(shlex.split("tcpdump -w myPackets.cap -i eth2 ip"),  stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    >>> a.terminate()
    >>> a.communicate()
    ('', 'tcpdump: listening on eth2, link-type EN10MB (Ethernet), capture size 65535 bytes\n221 packets captured\n221 packets received by filter\n0 packets dropped by kernel\n')
    


Answer: Use `proc.terminate()` instead of `proc.kill()`:

    
    
    import shlex
    import subprocess
    import time
    
    with open("tcpdumpSTDERR", "wb") as f_err: # close the file automatically
        proc = subprocess.Popen(shlex.split("tcpdump -w myPackets.cap -i eth2 ip"),
                                stderr=f_err)
    time.sleep(2)    # wait a few seconds
    proc.terminate() # send SIGTERM instead of SIGKILL
    proc.wait()      # avoid zombies
    

