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:

  1. make sure stdin popen pipe
  2. 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

Popular posts from this blog

Django REST Framework perform_create: You cannot call `.save()` after accessing `serializer.data` -

Why does Go error when trying to marshal this JSON? -