Reading os.popen() output returns nothing

Viewed 863

I'm developing a python script to gather several pieces of information about Linux systems, right now im trying to gather a list of the listening UDP e TCP ports using os.popen(), heres what the function looks like:

def ports(self):
    # Gets a few lines of information about open TCP ports
    tcpOpenPorts = os.popen("netstat -tulpn | grep -P 'tcp\b'").read()
    print(tcpOpenPorts)
    # Gets a few lines of information about open UDP ports
    udpOpenPorts = os.popen("netstat -tulpn | grep -P 'tcp\b'").read()
    print(udpOpenPorts)

The problem i'm facing is: when I execute the script using the function above both of the variables tcpOpenPorts and udpOpenPorts return empty, even though the shell command:

netstat -tulpn | grep -P 'tcp\b'

works normally.

Here's an example output of the command:

tcp        0      0 127.0.0.1:63342         0.0.0.0:*               OUÇA       3244/java
tcp        0      0 0.0.0.0:111             0.0.0.0:*               OUÇA       539/rpcbind
tcp        0      0 0.0.0.0:22              0.0.0.0:*               OUÇA       686/sshd
tcp        0      0 127.0.0.1:631           0.0.0.0:*               OUÇA       4466/cupsd
tcp        0      0 127.0.0.1:6942          0.0.0.0:*               OUÇA       3244/java

Is there anything wrong with the way i'm using the os module?

1 Answers

Single quotes stop the shell from processing backslashes, but the shell isn't the only thing that you need to stop from processing the backslash. Python string literal syntax also assigns special meaning to backslashes, so the shell is receiving a backspace character instead of a backslash and a b.

Use a raw string literal to avoid Python's backslash processing:

os.popen(r"netstat ...")

(Incidentally, I might ordinarily recommend using the subprocess module, but piping commands together with subprocess is awkward without using shell=True, and using shell=True defeats most of the benefit of subprocess. If you ever find yourself building command strings at runtime, though, definitely switch to subprocess instead of trying to handle things with string formatting.)

Related