pexpect like functionality for a subprocess in python

962 views Asked by At

I have a working code to retrieve the data from stdout of an ssh connection in chunks, check for a pattern match at the end of each chunk and send appropriate response back via stdin.

ssh = paramiko.SSHClient()
...
transport = ssh.get_transport()
session = transport.open_session()
session.set_combine_stderr(True)
session.get_pty()

stdin = session.makefile('wb', -1)
stdout = session.makefile('rb', -1)

session.exec_command(cmd)

for chunk in iter(lambda: session.recv(9999), ""):

  if re.search('Password: $', chunk):
    stdin.write(sudo_pw + '\n')
    stdin.flush()

  output += chunk

Now I have a subprocess using which I execute commands locally like below:

p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
(output, err) = p.communicate()

How can I implement the exact same logic of analyzing the output in chunks and send appropriate response via stdin? I am looking for a solution without using the pexpect.

1

There are 1 answers

0
meharo On

Found a solution which works the same way. In Linux, sudo prompt still can't be caught because it reads and writes directly to the detected terminal device. sudo -S works just fine.

master, slave = pty.openpty()

p = Popen(cmd, shell=True, stdout=slave, stdin=slave, stderr=STDOUT)

q = select.poll()
q.register(master,select.POLLIN)

output = ""

while True:
  if not q.poll(0):
    time.sleep(0.1)
    if p.poll() is not None:
      time.sleep(0.1)
      while q.poll(0):
        chunk = os.read(master, 9999)
        output += chunk
      break
  else:
    chunk = os.read(master, 9999)
    output += chunk

    if re.search('Password: $', chunk):
      os.write(master, sudo_pw + '\n')

rc = p.returncode