Search code examples
pythondictionarysubprocesspopen

How to use the contents of stdout in Python?


I am trying to run a terminal command(Linux) and use the output.

list = subprocess.Popen(
    'bgpq3 -j -A AS-FACEBOOK -m 24 -l Facebook',
    shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = list_prefixes.communicate()
print(stdout)

the output is:

 { "Facebook": [
    { "prefix": "5.45.32.0\/22", "exact": true },
    { "prefix": "185.160.58.0\/23", "exact": false, "greater-equal": 24, "less-equal": 24 },
    { "prefix": "5.57.248.0\/21", "exact": true },
    { "prefix": "5.206.208.0\/20", "exact": true },
    { "prefix": "185.54.94.0\/23", "exact": false, "greater-equal": 24, "less-equal": 24 },
    { "prefix": "31.193.104.0\/21", "exact": true },
    { "prefix": "213.233.192.0\/18", "exact": true },
    { "prefix": "217.26.96.0\/20", "exact": true }
] }

then I am trying to print each line using this code:

for item in stdout['Facebook']:
    if item['exact'] == 'true':
        print ("{}, {}".format(item['prefix'].split('\/')[0], item['exact']))
    else:
        print ("{}, {}".format(item['prefix'].split('\/')[0], item['greater-equal']))

But I get This error:

TypeError: string indices must be integers

The problem is de class type of stdout. when I use type(stdout) the result is:

<class 'str'>

Is there any way to fix this?


Solution

  • Use the json module to convert the string to a dict object.

    Ex:

    import json
    stdout = """{ "Facebook": [
        { "prefix": "5.45.32.0\/22", "exact": true },
        { "prefix": "185.160.58.0\/23", "exact": false, "greater-equal": 24, "less-equal": 24 },
        { "prefix": "5.57.248.0\/21", "exact": true },
        { "prefix": "5.206.208.0\/20", "exact": true },
        { "prefix": "185.54.94.0\/23", "exact": false, "greater-equal": 24, "less-equal": 24 },
        { "prefix": "31.193.104.0\/21", "exact": true },
        { "prefix": "213.233.192.0\/18", "exact": true },
        { "prefix": "217.26.96.0\/20", "exact": true }
    ] }"""
    
    stdout = json.loads(stdout)
    for item in stdout['Facebook']:
        if item['exact'] == 'true':
            print ("{}, {}".format(item['prefix'].split('\/')[0], item['exact']))
        else:
            print ("{}, {}".format(item['prefix'].split('\/')[0], item.get('greater-equal')))
    

    Output:

    5.45.32.0/22, None
    185.160.58.0/23, 24
    5.57.248.0/21, None
    5.206.208.0/20, None
    185.54.94.0/23, 24
    31.193.104.0/21, None
    213.233.192.0/18, None
    217.26.96.0/20, None
    

    Note: Some of the element do not have key 'greater-equal' so use item.get('greater-equal')