pythonsubprocesspopen

subproces.Popen with an or "|" symbol isn't working


I'm trying to list just the IP Address of my Wi-Fi network adapter to be able to detect if it is connected and has an IP address attached to it.

With this by itself it is working...

from subprocess import Popen

Popen([
    'netsh',
    'interface',
    'ip',
    'show',
    'addresses',
    'Wi-Fi'
]).communicate()

Output:

Configuration for interface "Wi-Fi"
    DHCP enabled:                         No
    IP Address:                           192.168.1.200
    Subnet Prefix:                        192.168.1.0/24 (mask 255.255.255.0)
    Default Gateway:                      192.168.1.1
    Gateway Metric:                       0
    InterfaceMetric:                      2

But, with this...

from subprocess import Popen

Popen([
    'netsh',
    'interface',
    'ip',
    'show',
    'addresses',
    'Wi-Fi',
    '|',
    'findstr',
    '/ir',
    'IP Address'
]).communicate()

with the or | symbol in the list, it is generating this...

Usage: show addresses  [[name=]<string>]

Parameters:

       Tag         Value
       name      - The name or index of a specific interface.

Remarks: Displays the IP address configuration for an interface or
         interfaces.

The information displayed for this command consists of:

Field              Description
-----              -----------
DHCP enabled       Shows whether the address comes from static or DHCP
                   configuration.
IP Address         Shows the IP address configured for an interface.
Subnet Mask        Shows the subnet mask associated with the IP address.
Default Gateway    Shows the IP address of a default gateway for the interface.
Gateway Metric     Shows the metric for the default gateway shown above.
                   Only applies if multiple default gateways are configured.
Interface Metric   Shows the metric for an interface.
                   Only applies if multiple interfaces are configured.

Examples:

       show addresses "Wired Ethernet Connection"

indicating that I typed in the wrong name of the adapter.

I've tried many combinations of the arguments of netsh in the list without any luck.

Does anyone have any Insight on this?

My best guess at the moment is that Popen doesn't know how to process the or | symbol.


Solution

  • I don't think that your output streams are being set correctly. When I run your code, I get:

    Configuration for interface "Wi-Fi"\
    ...my network info here...
    
    None
    

    When I remove your print statement, I don't get the None printout, but the net info is still printed... so it looks like your stdout var is getting set to None

    Doing some googling of my own, I came up with the following that could get you unstuck:

    from subprocess import PIPE, Popen
    
    command = [
        'netsh',
        'interface',
        'ip',
        'show',
        'addresses',
        'Wi-Fi',
        '|',
        'findstr',
        '/ir',
        'IP Address'
    ]
    with Popen(command, stdout=PIPE, stderr=None, shell=True) as process:
        output = process.communicate()[0].decode("utf-8")
        print(output)
    

    This produces:

    IP Address: <My-IP>

    Not completely sure what the issue is with your code, but if I remove the shell=True from my Popen call, I get the same error as you.