0

Program that I'm trying to run using shell command, outputs one word per second. I'm trying to execute a shell command within Python script and get realtime output on each word that is outputed. All the other solutions I found online, don't actually print the realtime output but rather one finished line at the time. I want to get the real realtime output where each word is printed out in realtime rather than each line. This is the code that I've tried:

cmd=['slowprogram','-m', '15', '-l', '50'] p = subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=1) for line in iter(p.stdout.readline, b''): print(line), p.stdout.close() p.wait() 

It waits until one line is finished and the prints it. Is there a way to get updates on and print each word in a line, in realtime?

UPDATE:

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=1) for line in iter(p.stdout.readline, b''): for word in iter(line): print(word) p.stdout.close() p.wait() 

returns a bunch of numbers for some reason...:

111 117 108 100 32 104 97 118 101 32 115 97 

How can I get each word from the line?

3
  • p.stdout is a io.BytesIO object; syntactically you can read however you want from it as if it's a file. You might also want to look into the bufsize argument depending on your need. Commented Oct 2, 2020 at 17:08
  • @YiFei I tried iterating each word in a line but output was unexpected. I've updated my question, could you please take a look? Commented Oct 3, 2020 at 19:43
  • @YiFei I still can't figure it out. Could you please show how to read p.stdout in realtime? Commented Oct 28, 2020 at 21:00

1 Answer 1

2

This is one way to do it and it worked for me in a Linux shell. It uses an unbuffered IO object and prints out one character at a time. I'm quite sure there are better ways since I'm not an expert on either subprocess or event handling. You may also want to look into asyncio.

with subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=0) as p: char = p.stdout.read(1) while char != b'': print(char.decode('UTF-8'), end='', flush=True) char = p.stdout.read(1) 
Sign up to request clarification or add additional context in comments.

7 Comments

How can I save the output to an array without 'b' before each word? When I'm appending char variable to an array, 'b' is shown before each word.
To rephrase: how can I save the whole output to an array?
A little context: Python deals with two types of "string": byte string and "text" string. What we capture from Popen is a byte string and hence the b. Now byte strings can be converted to text strings by decoding, and backwards by encoding.
I see. When I try to save the decoded chars to an array my words split up for some reason. ’Hello’ might turn into ’hel’ and ’lo’. Is there a way to save the whole output without rerunning the whole command?
Say you have a list (or any iterable for that matter) L = ['hel', 'lo'], you can use ''.join(L). But depending on your need, you may as well save and append to a string from the beginning.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.