2

I have an application that takes input, either from the terminal directly or I can use a pipe to pass the output of another program into the stdin of this one. What I am trying to do is use python to generate the output so it's formatted correctly and pass that to the stdin of this program all from the same script. Here is the code:

#!/usr/bin/python
import os 
import subprocess
import plistlib
import sys

def appScan():
    os.system("system_profiler -xml SPApplicationsDataType > apps.xml")
    appList = plistlib.readPlist("apps.xml")
    sys.stdout.write( "Mac_App_List\n"
    "Delimiters=\"^\"\n"
    "string50 string50\n"
    "Name^Version\n")
    appDict = appList[0]['_items']
    for x in appDict:
        if 'version' in x:
           print x['_name'] + "^" + x['version'] + "^"
        else:
           print x['_name'] + "^" + "no version found" + "^"
proc = subprocess.Popen(["/opt/altiris/notification/inventory/lib/helpers/aex-     sendcustominv","-t","-"], shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
proc.communicate(input=appScan())

For some reason this subprocess I am calling doesn't like what is coming into stdin. However if I remove the subprocess items and just have the script print to stdout and then call the script from the terminal (python appScan.py | aex-sendcustominv), aex-sendcustominv is able to accept the input just fine. Is there any way to take a functions output in python and send it to the stdin of an subprocess?

Dishwishy
  • 23
  • 1
  • 3
  • There is a similar SO question here- http://stackoverflow.com/questions/163542/python-how-do-i-pass-a-string-into-subprocess-popen-using-the-stdin-argument – beer_monk May 25 '11 at 22:03

1 Answers1

3

The problem is that appScan() only prints to stdout; appScan() returns None, so proc.communicate(input=appScan()) is equivalent to proc.communicate(input=None). You need appScan to return a string.

Try this (not tested):

def appScan():
    os.system("system_profiler -xml SPApplicationsDataType > apps.xml")
    appList = plistlib.readPlist("apps.xml")
    output_str = 'Delimiters="^"\nstring50 string50\nName^Version\n'
    appDict = appList[0]['_items']
    for x in appDict:
        if 'version' in x:
           output_str = output_str + x['_name'] + "^" + x['version'] + "^"
        else:
           output_str = output_str + x['_name'] + "^" + "no version found" + "^"
    return output_str

proc = subprocess.Popen(["/opt/altiris/notification/inventory/lib/helpers/aex-     sendcustominv","-t","-"], shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
proc.communicate(input=appScan())
senderle
  • 145,869
  • 36
  • 209
  • 233