Get output of subprocess without garbage

633 Views Asked by At

In the Transcrypt Python to JavaScript compiler, I use the following code to pipe data through a subprocess:

                process = subprocess.Popen (
                    [node.args [1] .s],
                    shell = True,
                    stdin = subprocess.PIPE,
                    stdout = subprocess.PIPE
                )
                process.stdin.write (sourceCode.encode ('utf8'))
                process.stdin.close ()
                while process.returncode is None:
                    process.poll ()
                targetCode = process.stdout.read (). decode ('utf8'). replace ('\r\n', '\n')

My subprocess is a Windows .bat file containing:

python capitalize.py

The contents of capitalize.py are:

import sys
content = sys.stdin.read ()
sys.stdout.write (content.upper ())

If variable sourceCode initially contains:

dit
is
een
test

as a result variable targetCode will contain:

    D:\activ_tosh\geatec\transcrypt\qquick\Transcrypt\transcrypt\development\experiments\pipe>python capitalize.py 

    D:\activ_tosh\geatec\transcrypt\qquick\Transcrypt\transcrypt\development\experiments\pipe>call D:\python36_anaconda\python.exe capitalize.py 

        DIT
        IS
        EEN
        TEST

In other words, the echo of the commands is prepended to stdout, as can be expected.

If I start the command file with echo off, that gets echoed, so it doesn't help.

How can I change the code of subprocess.Popen (or code surrounding it) such that targetCode will only contain:

        DIT
        IS
        EEN
        TEST

I've tried many things, including use of echo off in various places and reassigning stdout. And I've been Googling quite a lot, but found no solution. Anyone knows how to solve this?

[EDIT1] @Mahesh Karia

I've tried:

                process = subprocess.Popen (
                    [node.args [1] .s],
                    shell = True,
                    stdout = subprocess.PIPE
                )
                print (111)
                targetCode = process.communicate (io.StringIO (sourceCode))[0]
                print (222)

This hangs after printing 111.

[EDIT1]

I've solved my problem by using an executable (translated from C++) as a filter, rather than a .bat or a .py file. This doesn't generate any console echo.

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main () {
    string buffer;
    getline (cin, buffer, '\f');
    transform (buffer.begin(), buffer.end(), buffer.begin(), ::toupper);
    cout << buffer;
}

The input data has to end on a termination char, in this case I've used '\f':

'''
<div id="StudentContainer">
    {self.props.students.map((s) => (
        <StudentTile student={s}  key={s.searchval}  />
    ))}
</div>
\f'''
1

There are 1 best solutions below

5
On

One way is to use communicate() to get output.

processes = [Popen(cmd, shell=True, stdout=subprocess.PIPE) for cmd in self.cmd_list]
for p in processes: p.wait()
for p in processes:
    output = p.communicate()[0]
    print output