jest to możliwe, aby zmodyfikować kod poniżej mieć wydruk „standardowe wyjście” i «»: stderrsubprocess.Popen: Klonowanie i stderr zarówno standardowe wyjście do zacisku i zmienne
- drukowane na terminalu(w czasie rzeczywistym czas),
- i ostatecznie przechowywane w outach i errs zmiennych?
Kod:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import subprocess
def run_cmd(command, cwd=None):
p = subprocess.Popen(command, cwd=cwd, shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
outs, errs = p.communicate()
rc = p.returncode
outs = outs.decode('utf-8')
errs = errs.decode('utf-8')
return (rc, (outs, errs))
Dzięki @unutbu, specjalne podziękowania dla @ JF Sebastian, ostateczną funkcję:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
from queue import Queue
from subprocess import PIPE, Popen
from threading import Thread
def read_output(pipe, funcs):
for line in iter(pipe.readline, b''):
for func in funcs:
func(line.decode('utf-8'))
pipe.close()
def write_output(get):
for line in iter(get, None):
sys.stdout.write(line)
def run_cmd(command, cwd=None, passthrough=True):
outs, errs = None, None
proc = Popen(
command,
cwd=cwd,
shell=False,
close_fds=True,
stdout=PIPE,
stderr=PIPE,
bufsize=1
)
if passthrough:
outs, errs = [], []
q = Queue()
stdout_thread = Thread(
target=read_output, args=(proc.stdout, [q.put, outs.append])
)
stderr_thread = Thread(
target=read_output, args=(proc.stderr, [q.put, errs.append])
)
writer_thread = Thread(
target=write_output, args=(q.get,)
)
for t in (stdout_thread, stderr_thread, writer_thread):
t.daemon = True
t.start()
proc.wait()
for t in (stdout_thread, stderr_thread):
t.join()
q.put(None)
outs = ' '.join(outs)
errs = ' '.join(errs)
else:
outs, errs = proc.communicate()
outs = '' if outs == None else outs.decode('utf-8')
errs = '' if errs == None else errs.decode('utf-8')
rc = proc.returncode
return (rc, (outs, errs))
Przykładowy kod sklep 'outs' i 'errs' i zwraca je ... Aby wydrukować do terminala, po prostu' jeśli out: print out' 'if errs: print errs' – bnlucas
@ bnlucas Dzięki, ale jak stwierdziłem w pierwszym punkcie: dane wyjściowe powinny być wydrukowane w PRAWDZIWY CZAS do terminala, podobnie jak bez PIPE. –
Jeśli potrzebujesz kodu Python 3; dodaj tag [tag: python-3.x] (widzę python3 w shebangu). Twój napisany kod pozostawi wiszące wątki do czytania. W języku Python 3 '' 'jest literałem w standardzie Unicode, ale' pipe.readline() 'zwraca bajty domyślnie (' '!! B" "' w Pythonie 3). Jeśli to naprawisz, wątek pisarza się nie skończy, ponieważ nic nie umieszcza '' "' w kolejce. – jfs