Python - How to get the output of running a . py file to a . txt

Asked

Viewed 421 times

4

I have the following command:

python3 -u teste.py > saida.txt 2>&1

This command causes the execution output of the teste.py be sent to this file saida.txt, case saida.txt does not exist it is created. The teste.py never for its execution because it is a Thread, that is, the file of teste.py is always trying to write new information on saida.txt, what causes, when trying to edit the file saida.txt while teste.pyis running, lose the reference and it stops filling the file saida.txtwith information on the implementation of teste.py.

Failed to try to edit the file saida.txt in this way, I opted for another method using python3:

from threading import Thread
from time import sleep
import subprocess as sp

class teste(Thread):
    def __init__(self):

        Thread.__init__(self)

        self.cmd  = ['python3 -u teste.py']
        self.proc = sp.Popen(self.cmd, shell = True,
                                     stdout=sp.PIPE,
                                     stderr=sp.PIPE,
                                     stdin=sp.PIPE)        

    def run(self):

        while True:

            sleep(1)

            self.output = self.proc.stdout.read().decode('utf-8')
            self.error  = self.proc.stderr.read().decode('utf-8')        
            print(self.output)
            print(self.error)

            # Caso eu conseguisse ler a saída eu passaria estas informações
            # Para um arquivo .txt

et = teste()
et.start()

But I did not succeed in reading the output of teste.py through the prints, no results and no type of error were generated.

The content of teste.py It’s very simple, it would be something like:

from time import sleep

while 1:
    print('saída')
    sleep(1)

NOTE: Too many quotations to teste.py and saida.txt were intended to make clear the process.

1 answer

2


First, self.proc.stdout.read(), will block your call until the program closes, and so you get nothing.

To do what you want, you need two threads, as follows:

def print_lines(inp):
    line = inp.readline().decode('utf-8')
    while line:
        print(line, end='')
        line = inp.readline().decode('utf-8')

proc = sp.Popen(['python3 -u teste.py'], shell=True, stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE)

t1 = Thread(target=print_lines, args=(proc.stdout,))
t2 = Thread(target=print_lines, args=(proc.stderr,))

t1.start()
t2.start()

t1.join()
t2.join()

In that publication, you can find a version single threaded, reading of the two streams using pseudo-terminal Utilities, apparently by a problem of bufferizing (reading response time) in solution as proposed above.

Below I leave also, another teste.py including writing in stderr:

import sys
from time import sleep

for _ in range(5):
    print('saída')
    sleep(0.3)

sys.stderr.write("acabou\n")
  • 1

    It worked perfectly! Thank you :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.