This question is similar to Run interactive Bash with popen and a dedicated TTY Python, except that I want to run Bash in a "dumb" terminal (TERM=dumb
), and without putting the tty into raw mode.
The code below is my attempt. The code is similar to the solution given in the linked question, with the major difference that it does not put the tty into raw mode, and sets TERM=dumb
.
import os
import pty
import select
import subprocess
import sys
master_fd, slave_fd = pty.openpty()
p = subprocess.Popen(['bash'],
stdin=slave_fd,
stdout=slave_fd,
stderr=slave_fd,
# Run in a new process group to enable bash's job control.
preexec_fn=os.setsid,
# Run bash in "dumb" terminal.
env=dict(os.environ, TERM='dumb'))
while p.poll() is None:
r, w, e = select.select([sys.stdin, master_fd], [], [])
if sys.stdin in r:
user_input = os.read(sys.stdin.fileno(), 10240)
os.write(master_fd, user_input)
elif master_fd in r:
output = os.read(master_fd, 10240)
os.write(sys.stdout.fileno(), output)
There are two problems with the code above:
- The code will re-echo whatever the user inputs. For example, if the user inputs
printf ''
, the code above will printprintf ''
on the next line before printing the next bash prompt. - Ctrlc and Ctrld do not behave as one would expect in
bash
.
How should I fix these problems?