Skip to content

Instantly share code, notes, and snippets.

@thomasballinger
Created December 15, 2013 23:26
Show Gist options
  • Star 24 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save thomasballinger/7979808 to your computer and use it in GitHub Desktop.
Save thomasballinger/7979808 to your computer and use it in GitHub Desktop.
Using a pseudo-terminal to interact with interactive Python in a subprocess
from subprocess import Popen, PIPE
import pty
import os
from select import select
import sys
import tty
master, slave = pty.openpty()
p = Popen(['python'], stdin=slave, stdout=PIPE, stderr=PIPE)
pin = os.fdopen(master, 'w')
tty.setcbreak(sys.stdin)
msg = ''
errmsg = ''
while True:
rs, ws, es = select([sys.stdin, p.stdout, p.stderr], [], [])
for r in rs:
if r is sys.stdin:
c = r.read(1)
if c == '':
msg = msg[:-1]
elif c == '\n':
pin.write(msg+'\n')
print '\r>>> %s' % msg
msg = ''
else:
msg += c
print '\r '+ ' '*(len(msg)+1),
print '\r>>> %s' % msg,
sys.stdout.flush()
elif r is p.stdout:
print p.stdout.readline(),
sys.stderr.flush()
elif r is p.stderr:
errmsg += p.stderr.read(1)
if errmsg.endswith('>>> '):
errmsg = errmsg[:-4]
if errmsg.endswith('\n'):
print 'ERR~%s' % (errmsg,),
errmsg = ''
@lubyagin
Copy link

Thomas, please see my code: https://github.com/lubyagin/rubash/blob/master/linux.py
I am writing pseudo-terminal too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment