0

I'm trying to write a script that will use netstat to check ephemeral ports on a windows machine. When I test this script in the IDLE on Windows, it returns with a 0.

Here is my code that I'm testing:

import os
oPorts=os.system('netstat -ano | find /i \"estab\" /c')
print(oPorts)

Here is what happens when I try to run that in Python:

os.system Python Script]1

Here's the output however when I run the same thing in command prompt.

cmd prompt output

So why is Python outputting a 0 when there are clearly about 311 established connections on the Windows host? What am I missing?

RaptorPete
  • 139
  • 12

3 Answers3

3

The os.system function returns the exit status of the command.Not the output of the command. You should be using the subprocess module instead. Then you can capture the output.

Keith
  • 42,110
  • 11
  • 57
  • 76
  • Okay so here's my new code: `proc = subprocess.check_output('netstat -ano | find /i \"estab\" /c', stderr=subprocess.STDOUT, shell=True)` . This actually does return the correct number but there is also jargon before and after it. Instead of just returning "330" for example it returns "b'330\r\n" . How do I get rid of that other junk and just have it return an integer? – RaptorPete Nov 16 '18 at 16:26
  • @RaptorPete On the returned bytes object do: `oPorts = oProts.decode("ascii").strip()`. – Keith Nov 17 '18 at 03:17
0

The return value from an executable process is not the same as its output. By convention a process returns 0 to indicate success and anything else to indicate failure. When you run a command from the command line, thbe return value is not typically printed. To capture the output, you need to redirect stdout.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • If you see below under Keith's response I was able to change up my code and get a number output. But now it's also including some other random characters. Any idea how I can change the output of b'330\r\n to just say "330"? Thanks – RaptorPete Nov 16 '18 at 16:30
  • @RaptorPete The notation `b''` is python's way of telling you that this is binary data. You can call `decode()` on it (with the correct encoding name) to convert it to a string. – Code-Apprentice Nov 16 '18 at 17:29
0

The following code gave me exactly the output I was intending.

import subprocess

established = (subprocess.Popen('netstat -ano | find /i \"estab\" /c',
                               stdout=subprocess.PIPE,
                               shell=True).communicate()[0].decode('utf-8').strip())

I'm not sure the difference exactly between check_output and Popen, but Popen and .communicate()[0].decode('utf-8').strip()) were the keys.

RaptorPete
  • 139
  • 12
  • 1
    `Popen` is the class that implements the core features. `call`, `check_call`, and `check_output` are convenience functions that wrap `Popen`. Recent versions of Python 3 also have a more generic `run` convenience function. They've also added `encoding` and `errors` parameters for all these functions. – Eryk Sun Nov 16 '18 at 22:34