1

When running this command with Python

p = Popen(['netstat', '-atunp'], shell=True, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
print stdout

I'm getting a different output. That is, if I run the same command from command line, I can see IP addresses and application names, whereas with Python I cannot.

Is there anything else I need to do to see IP addresses and app names?

Bob
  • 553
  • 1
  • 5
  • 10
  • Can you show us the output you are getting ? – fixxxer May 04 '15 at 19:24
  • 2
    drop `shell=True`. See [Don't use a list argument together with shell=True in subprocess' docs](http://bugs.python.org/issue21347) – jfs May 09 '15 at 18:17

1 Answers1

1

I think I ran your command without the -p flag. This flag expects a protocol. This is probably why your stdout string is empty; stderr on the other hand would have the error -

In [86]: stderr
Out[86]: 'netstat: option requires an argument -- p\nUsage:\tnetstat [-AaLlnW] [-f address_family | -p protocol]\n\tnetstat [-gilns] [-f address_family]\n\tnetstat -i | -I interface [-w wait] [-abdgRt]\n\tnetstat -s [-s] [-f address_family | -p protocol] [-w wait]\n\tnetstat -i | -I interface -s [-f address_family | -p protocol]\n\tnetstat -m [-m]\n\tnetstat -r [-Aaln] [-f address_family]\n\tnetstat -rs [-s]\n\n'

So update your command like this (removing shell=True and adding a protocol as an argument) -

In [87]: paste
p = Popen(['netstat', '-atunp', 'tcp'], stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
print stdout

## -- End pasted text --
Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)    
tcp4       0      0  192.168.1.100.53076    198.252.206.140.80     ESTABLISHED
tcp4       0      0  192.168.1.100.53075    198.252.206.140.80     ESTABLISHED
tcp4       0      0  192.168.1.100.53004    216.58.220.3.443       ESTABLISHED
tcp4       0      0  192.168.1.100.52984    74.125.200.155.443     ESTABLISHED
tcp4       0      0  192.168.1.100.52954    198.252.206.149.443    ESTABLISHED
tcp4       0      0  192.168.1.100.52927    91.189.89.222.443      FIN_WAIT_1 
tcp4       0      0  192.168.1.100.52925    173.194.120.144.443    ESTABLISHED
tcp4       0      0  192.168.1.100.52869    74.125.130.155.443     ESTABLISHED
tcp4       0      0  192.168.1.100.52863    74.125.68.139.443      ESTABLISHED
tcp4       0      0  192.168.1.100.52858    74.125.130.102.443     ESTABLISHED
tcp4       0      0  192.168.1.100.52851    74.125.68.93.443       ESTABLISHED
tcp4       0      0  192.168.1.100.52847    74.125.200.132.443     ESTABLISHED
tcp4       0      0  192.168.1.100.52814    216.58.216.163.443     ESTABLISHED
tcp4       0      0  192.168.1.100.52812    74.125.68.189.443      ESTABLISHED
tcp4       0      0  192.168.1.100.52794    74.125.130.17.443      ESTABLISHED
tcp4       0      0  192.168.1.100.52793    198.252.206.149.443    ESTABLISHED
tcp4       0      0  192.168.1.100.52761    74.125.68.138.443      ESTABLISHED
tcp4       0      0  192.168.1.100.52737    74.125.68.132.443      ESTABLISHED
tcp4       0      0  192.168.1.100.52577    17.172.232.205.443     ESTABLISHED
tcp4       0      0  192.168.1.100.52571    74.125.130.188.443     ESTABLISHED
tcp6       0      0  fd9a:f3a0:3346:7.4488  *.*                    LISTEN     
tcp4       0      0  *.*                    *.*                    CLOSED     
tcp4       0      0  127.0.0.1.631          *.*                    LISTEN     
tcp6       0      0  ::1.631                *.*                    LISTEN     
fixxxer
  • 15,568
  • 15
  • 58
  • 76
  • `print stdout` from the question works as is already. The issue is probably similar to [Last unbuffered line can't be read](http://stackoverflow.com/q/25923901/4279) – jfs May 09 '15 at 18:16
  • As I understand it, OP wants netstat output decorated like he sees on the command line. Splitting based on new lines, we get the same output as the terminal. – fixxxer May 09 '15 at 18:26
  • no. It is not correct. `stdout` is a string (with possible embed newlines (`'\n'` characters)). `stdout.split('\n')` returns a Python list. The output that you see is `repr(the_list)` that is **not** what the terminal would show. – jfs May 09 '15 at 18:29
  • Agreed on that it isn't what the terminal would show. I was commenting on the part where a nicely stacked list of values makes more sense than visually scrambled string. – fixxxer May 09 '15 at 18:34
  • @J.F.Sebastian Updated the answer. What do you think? – fixxxer May 09 '15 at 18:41
  • yes. [As I've mentioned](http://stackoverflow.com/questions/30037671/netstat-not-working-properly-with-popen/30038401?noredirect=1#comment48395469_30037671) dropping `shell=True` may fix the issue. There could be another issue if `netstat` changes its output depending on whether stdout is connected to a terminal or redirected to a pipe (see [the link in the first comment](http://stackoverflow.com/q/25923901/4279)). – jfs May 09 '15 at 18:53
  • Had disabled `shell` based on your comment. Second link answered an old question which I never asked on SO. But would it be right to say that `netstat` changes its output ? Shouldn't it be the OS ? – fixxxer May 09 '15 at 18:59
  • The application changes its behavior. You can do it yourself: `print("terminal" if sys.stdin.isatty() else "not a tty")` – jfs May 09 '15 at 19:14