Python - read output from long-running subprocess [duplicate] - python

This question already has answers here:
Read streaming input from subprocess.communicate()
(7 answers)
Closed 6 years ago.
Using the subprocess module (Python 2.7), I'm running a command and attempting to process its output as it runs.
I have code like the following:
process = subprocess.Popen(
['udevadm', 'monitor', '--subsystem=usb', '--property'],
stdout=subprocess.PIPE)
for line in iter(process.stdout.readline, ''):
print(line)
However, the output only gets printed after I Ctrl+C, even if I add sys.stdout.flush() after the print statement.
Why is this happening, and how can I live stream the output from this process?
Notably, this udevadm monitor command is not intended to terminate, so I can't simply wait for the process to terminate and process its output all at once.
I found live output from subprocess command but the approach in the accepted answer did not solve my problem.

You could use unbuffer :
process = subprocess.Popen(
["unbuffer", 'udevadm', 'monitor', '--subsystem=usb', '--property'],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in iter(process.stdout.readline, ''):
print(line)

Related

Run tail command as background process in Python [duplicate]

This question already has answers here:
Read streaming input from subprocess.communicate()
(7 answers)
Closed last year.
I have file named test.py and I am trying to run below command as a background process as part of this script
"tail -n0 -f debug.log"
Also, I want this process to end as soon as test.py execution is completed.
However, I can't get this to working. I have tried below code but tail command not exiting even after main script is completed.
I am new Python, can someone help me do this clean way ?
pro = subprocess.Popen(["tail", "-n0", "-f", log_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in pro.stdout:
print(line)
os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
I used it once before, so I can't remember exactly, but I think I exiting 'subprocess.Popen' using 'with'. I'm not sure, but I recommend giving it a try.
with subprocess.Popen(["tail", "-n0", "-f", log_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as pro:
for line in pro.stdout:
print(line)

Why is log.plaintext responding late in Python? [duplicate]

This question already has answers here:
Run command with PyQt5 and getting the stdout and stderr
(2 answers)
How to keep PyQt5 responsive when calling gnuplot?
(1 answer)
Closed 1 year ago.
I want to see the immediate execution result of stdout after exe's execution on pyqt. I implemented all the actions I want in Python code, and the rest are linked to pyqt's widget. I want to print out the immediate execution result of exe from pyqt. Though everything outputs normally in the cmd window, while only log.insertPlainText part output shows at the last time after all the cmd execution ends.
I am sure this is not a duplicate question. What I want is not a solution from pyqt, but I want to solve it entirely with Python code. I've tried many different things, but the log is still printed all at once at the end of the cmd execution. The reason I used log.insertPlainText instead of print is, because I want to show the output result in pyqt.
What I already tried:
cmd = [cmd command]
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, universal_newlines=True, bufsize=1)
for line in iter(p.stdout):
log.insertPlainText(line)
p.stdout.close()
p.wait()
and
with Popen([cmd command], stdout=PIPE, bufsize=1,
universal_newlines=True) as p:
for line in p.stdout:
log.insertPlainText(line)

Live output status from subprocess command Python [duplicate]

This question already has answers here:
live output from subprocess command
(21 answers)
Closed 2 years ago.
I'm writing a script to get netstat status using subprocess.check_output.
cmd = 'netstat -nlpt'
result = subprocess.check_output(cmd, shell=True, timeout=1800)
print(result.decode('utf-8'))
The above is running perfectly. Is there any way to get the live-streaming output. I have heard poll() function does this job. In live output from subprocess command they are using popen but i'm using check_output please some one help me on this issue. Thank you!
From this answer:
The difference between check_output and Popen is that, while popen is a non-blocking function (meaning you can continue the execution of the program without waiting the call to finish), check_output is blocking.
Meaning if you are using subprocess.check_output(), you cannot have a live output.
Try switching to Popen().

subprocess.Popen not printing/running properly [duplicate]

This question already has answers here:
Read streaming input from subprocess.communicate()
(7 answers)
Closed 7 years ago.
I have a script that reads from external sensors (and runs forever), when I run it as ./zwmeter /dev/ttyUSB0 300 it behaves normally and prints output continuously to stdout. I am using bash on Ubuntu. I'd like to execute this command as part of a python script. I have tried:
from subprocess import Popen, PIPE
proc = Popen(['./zwmeter', '/dev/ttyUSB0', '300'], stderr=PIPE, stdout=PIPE)
print proc.communicate()
but I get a program that runs forever without producing any output. I don't care about stderr, only stdout and have tried splitting up the printing but still with no success.
Thank you for any help you can provide!
I think the problem has to do with the process I'm calling not terminating. I found a good work around on this site:
http://eyalarubas.com/python-subproc-nonblock.html

Capture subprocess output [duplicate]

This question already has answers here:
Read streaming input from subprocess.communicate()
(7 answers)
Closed 6 years ago.
I learned that when executing commands in Python, I should use subprocess.
What I'm trying to achieve is to encode a file via ffmpeg and observe the program output until the file is done. Ffmpeg logs the progress to stderr.
If I try something like this:
child = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE)
complete = False
while not complete:
stderr = child.communicate()
# Get progress
print "Progress here later"
if child.poll() is not None:
complete = True
time.sleep(2)
the programm does not continue after calling child.communicate() and waits for the command to complete. Is there any other way to follow the output?
communicate() blocks until the child process returns, so the rest of the lines in your loop will only get executed after the child process has finished running. Reading from stderr will block too, unless you read character by character like so:
import subprocess
import sys
child = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE)
while True:
out = child.stderr.read(1)
if out == '' and child.poll() != None:
break
if out != '':
sys.stdout.write(out)
sys.stdout.flush()
This will provide you with real-time output. Taken from Nadia's answer here.
.communicate() "Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate."
Instead, you should be able to just read from child.stderr like an ordinary file.

Categories