Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I know whether my subprocess is waiting for my input ?(in python3)

file sp.py:

#!/usr/bin/env python3
s = input('Waiting for your input:')
print('Data:' + s)

file main.py

import subprocess as sp
pobj = sp.Popen('sp.py',stdin=sp.PIPE,stdout=sp.PIPE,shell=True)
print(pobj.stdout.read().decode())
pobj.stdin.write(b'something...')
print(pobj.stdout.read().decode())

main.py will block in the first pobj.stdout.read(), because sp.py is waiting for me.
But if I want to process the string 'Waiting for you input:' first, how can I know whether sp.py is waiting for me ?
In other words, I want the pobj.stdout.read() to return when sp.py is waiting (or sleeping because of time.sleep()).

like image 332
Richard Tsai Avatar asked Aug 29 '12 14:08

Richard Tsai


People also ask

How do I know if subprocess is running?

If you do not have the process instance in hand to check it. Then use the operating system TaskList / Ps processes. The ps command will already be returning error code 0 / 1 depending on whether the process is found. While on windows you need the find string command.

Does subprocess run wait?

subprocess. run() is synchronous which means that the system will wait till it finishes before moving on to the next command. subprocess. Popen() does the same thing but it is asynchronous (the system will not wait for it to finish).

How do I know if Python is running Popen?

Popen has a built-in method to determine if the subprocess is still running, Popen. poll(). In your code process. Popen.

How do you find the output of a subprocess run?

To capture the output of the subprocess. run method, use an additional argument named “capture_output=True”. You can individually access stdout and stderr values by using “output. stdout” and “output.


1 Answers

Okay, I've worked it out. My code is based on Non-blocking read on a subprocess.PIPE in python (Thanks, @VaughnCato)

#!/usr/bin/env python3
import subprocess as sp
from threading import Thread
from queue import Queue,Empty
import time

def getabit(o,q):
    for c in iter(lambda:o.read(1),b''):
        q.put(c)
    o.close()

def getdata(q):
    r = b''
    while True:
        try:
            c = q.get(False)
        except Empty:
            break
        else:
            r += c
    return r

pobj = sp.Popen('sp.py',stdin=sp.PIPE,stdout=sp.PIPE,shell=True)
q = Queue()
t = Thread(target=getabit,args=(pobj.stdout,q))
t.daemon = True
t.start()

while True:
    print('Sleep for 1 second...')
    time.sleep(1)#to ensure that the data will be processed completely
    print('Data received:' + getdata(q).decode())
    if not t.isAlive():
        break
    in_dat = input('Your data to input:')
    pobj.stdin.write(bytes(in_dat,'utf-8'))
    pobj.stdin.write(b'\n')
    pobj.stdin.flush()
like image 117
Richard Tsai Avatar answered Sep 28 '22 07:09

Richard Tsai