1
votes

PYTHON VERSION - 3.5.2 OS - Ubuntu 16.04 LTS

I am currently using both stdout and print statements to write to the terminal. I want to capture the output of ONLY sys.stdout.write command and not the print commands So for eg if my code is -

import sys
sys.stdout.write("Hello")
print("PRINT")

I want to capture only "Hello" and not "PRINT".

I am currently using this :

x = subprocess.run(['python3 test.py'] , shell = True , stdout = subprocess.PIPE).stdout.decode('utf-8')

which gives me this output:

['HelloPRINT', '']
3
print() uses sys.stdout.write() to display text. But suproccess see only text send by system and it doesn't know what you used to send text to system. - furas
print writes to sys.stdout by default. You can, however, override this behavior in the file argument of the print function. - iz_
you can only redirect print() to file or stderr but you have to do it in code print("Print", file=sys.stderr) - furas
So when I redirect it to sys.stderr what happens to the text ? - Tanmay Bhatnagar
when you will run it in console/terminal then you will see all text - stdout` and stderr - but subprocess will get only stdout because you set only stdout = subprocess.PIPE - furas

3 Answers

2
votes

print() uses sys.stdout.write() to display text .

Besides suproccess see only text send by system and it doesn't know what you used to send text to system.

You can only in code redirect print() to sys.stderr

import sys
sys.stdout.write("Hello")
print("PRINT", file=sys.stderr)

and then you will still see all text when you run in console but you will get only sys.stdout when you use subprocess

You will also get only stdout in file if you use in console

python script.py > stdout.txt

or you redirect to other program

python script.py | sort

Instead of print(... ,file=sys.stderr) you can also use sys.stderr.write("PRINT\n") but you have to add "\n" at the end manually.

1
votes

You can't do this because print() uses sys.stdout.write() internally. The following REPL session illustrates this:

>>> import sys
>>> class StdoutProxy:
...  def write(self, text):
...   return len(text) # do nothing
...
>>> sys.stdout = StdoutProxy()
>>> print("Hello!")
>>> sys.stdout = sys.__stdout__  # reset stdout to its original state
>>> print("Hello!")
Hello!
1
votes

You can define your own version of the print function like this:

import sys

def get_my_print(file=sys.stdout):
    _original_print = print
    def my_print(*objects, sep='', end='\n', file=file, flush=False):
        _original_print(*objects, sep='', end='\n', file=file, flush=False)
    return my_print

original_print = print
print("Redirect print to stderr...")
print = get_my_print(sys.stderr)

print("Print some numbers...")
for x in range(10):
    print(x)

print = original_print
print("Done.")

Console

$ python3 redirect_print.py 1> /dev/null
Print some numbers...
0
1
2
3
4
5
6
7
8
9