David Torrey
David Torrey

Reputation: 1352

Python Subprocess controlling output

I have a base python project which can accept other python files and execute them as a sub-process. The base project accepts user input, feeds it to the sub-process which then executes code and returns a value via stdout which is fed back to the user.

In the base program I'm doing something similar to:

dataReturnValue = subprocess.check_output(['python', pythonScriptPath, json.dumps(inputParams)])

then in the subprocess I have something like this:

inputParams = sys.argv[1]
...
...
sys.stdout.write(returnValue)

The data is correctly returned, but what I'd like to do is have the data returned be limited to the returnValue. Right now it returns all print statements throughout the subprocess plus the return value. This makes sense to me since it's a form of output and print is akin to a stdout wrapper, but I'd like to better control this.

Is there a way to clear the stdout buffer just prior to my final output statement so that there are no stray prints or outputs included in the value returned from the sub-process?

Edit: I've tried doing a sys.stdout.buffer.flush(), sys.stdout.flush() just prior to the final call in hopes that it would clear out the buffer but the print statements prior still appear to be sent with the final return value.

Upvotes: 0

Views: 446

Answers (3)

pankaj mishra
pankaj mishra

Reputation: 2615

May be this can help you.

You can use subprocess Popen,PIPE to do your task.if you wish to use multiple subprocess instances here is the link

Python subprocess: how to use pipes thrice?

How to control the output ?

below command(dummy command) will generate 100 of lines , but i need only one line which have text 'Appium Started'

from subprocess import Popen,PIPE
command='appium-p 4723'
p1=Popen(command,stdout=Pipe)

return_value= 'Started Appium'

#this will store the output which command generated 
output = p3.communicate()[0]

for line in output:
    if returnvalue in line:
        print line
    else:
        pass

in the end you only get the line which you wanted i.e. Appium Started

Upvotes: 0

Myles Hollowed
Myles Hollowed

Reputation: 546

Try this:

import sys
import os

# Your code here

with open(os.devnull, 'w') as sys.stdout:
    # Code that you don't want to be printed here
sys.stdout = sys.__stdout__

# Your code here

Edit:

I even made it into a decorator for you

import sys
import os

def silence(func, *args, **kwargs):
    def wrapper(*args, **kwargs):
        with open(os.devnull, 'w') as sys.stdout:
            result = func(*args, **kwargs)
        sys.__dict__['stdout'] = sys.__stdout__
        return result
     return wrapper

Use it on any function like this:

def test1():
    print("TEST1")

@silence
def test2():
    print("TEST2")

def test3():
    print("TEST3")

test1()
test2()
test3()

Output:

TEST1
TEST3

Upvotes: 1

cosmic_inquiry
cosmic_inquiry

Reputation: 2684

this might not be the answer you are looking for, but perhaps this is a possible workaround:

dataReturnValue = dataReturnValue.split("\n")[-1]

Upvotes: 0

Related Questions