python - Communicate with process send key in subprocess linux -
i have 1 sh file, need install in target linux box. i'm in process of writing automatic installation sh file required lot of input user. example, first thing made ./file.sh
show big paragaraph , ask user press enter
. i'm stuck in place. how send key data sub process. here i've tried.
import subprocess def runprocess(exe): global p p = subprocess.popen(exe, stdout=subprocess.pipe, stderr=subprocess.stdout) while(true): retcode = p.poll() #returns none while subprocess running line = p.stdout.readline() yield line if(retcode not none): break line in runprocess('./file.sh'.split()): if '[enter]' in line: print line + 'got it' p.communicate('\r')
correct me if understanding wrong, pardon me if duplicate.
if need send bunch of newlines , nothing else, need to:
- make sure
stdin
popen
pipe - send newlines without causing deadlock
your current code neither. might work (assuming they're not using apis require direct interaction in tty, rather reading stdin
):
import subprocess import threading def feednewlines(f): try: # write many newlines take while true: f.write(b'\n') # write newline, not carriage return f.flush() # flush ensure it's sent possible except oserror: return # done when pipe closed/process exited def runprocess(exe): global p # stdin pipe p = subprocess.popen(exe, stdin=subprocess.pipe, stdout=subprocess.pipe, stderr=subprocess.stdout) # use thread feed many newlines needed stdin of subprocess feeder = threading.thread(target=feednewlines, args=(p.stdin,)) feeder.daemon = true feeder.start() # no need poll, read until closes stdout or exits line in p.stdout: yield line p.stdin.close() # stop feeding (causes thread error , exit) p.wait() # cleanup process # iterate output, , echo when [enter] seen line in runprocess('./file.sh'.split()): if '[enter]' in line: print line + 'got it'
for case need customize responses, you're going need add communication between parent , feeder thread, makes uglier, , works if child process flushing output when prompts you, when not connected terminal. might define global queue:
import queue # queue on python 2 feederqueue = queue.queue()
then change feeder function to:
def feednewlines(f): try: while true: f.write(feederqueue.get()) f.flush() except oserror: return
and change global code lower down to:
for line in runprocess('./file.sh'.split()): if '[enter]' in line: print line + 'got it' feederqueue.put(b'\n') elif 'thing requires type foo' in line: feederqueue.put(b'foo\n')
etc.
Comments
Post a Comment