如何在单独的进程中运行一个shell并获得自动完成? (python)

我有一个Linux应用程序,从一些设备获取inputstream。 这个input应该被引导到一个shell进程,以便它模拟给用户一个标准的shell。 到目前为止,我已经通过创build运行'/ bin / sh'的进程来完成它,并且我redirect了其input,输出和stderr,如下所示:

import subprocess p = subprocess.Popen(shell=False, args=['/bin/sh'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) _make_nonblocking(p.stdout) # sets O_NONBLOCK _make_nonblocking(p.stderr) 

当我只是一个通行命令,一切正常。

 p.stdin.write('pwd\n') p.stdout.read() '/home/dave\n' 

对于自动完成,我试图写:

 p.stdin.write('ls s\t') p.stdout.read() IOError: [Errno 11] Resource temporarily unavailable 

我希望得到一个可能的完成列表,但没有任何反应,直到我把“\ N”在标准input。 (另外,stderr没有什么等待)。

我已经查看了telnetd代码,并看到使用pty。 我尝试使用pty.openpty()并将slave设置为stdin,但是这也不起作用。 应该怎么办?

更新:我用build议的-i参数。 现在我有一个问题,一旦我使用Popen,然后按ENTER键,python shell移动到后台,如下所示:

 >>> p = subprocess.Popen(shell=False, args=['/bin/sh', '-i'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) >>> <ENTER> [1]+ Stopped ipython $ 

Solutions Collecting From Web of "如何在单独的进程中运行一个shell并获得自动完成? (python)"

使用bash autocompletion只能在交互模式下工作:

 -i If the -i option is present, the shell is interactive. 

这将做适当的仿真,包括显示提示和所有常用的东西。

最终要彻底解决所有问题,我不得不做几件事情:

  1. 配置一个pty设备(在Python中使用pty模块)。
  2. 使用termios(回声,信号处理等)设置适当的标志。
  3. 开始新的会话(以便信号不会传播原始进程)。
  4. 使用未缓冲的文件(在bufsize中传递0)打开pty设备。

这是工作的代码:

 def prepare(): os.setsid() # start a new detached session tty.setcbreak(sys.stdin) # set standard input to cbreak mode old = termios.tcgetattr(sys.stdin) old[0] |= termios.BRKINT # transforms break to SIGINT old[3] &= termios.ICANON # non-canonical mode old[3] |= termios.ECHO | termios.ISIG # set echo and signal characters handling cc = old[6] # make input unbuffered cc[termios.VMIN] = 1 cc[termios.VTIME] = 0 termios.tcsetattr(sys.stdin, termios.TCSANOW, old) master, slave = pty.openpty() master = os.fdopen(master, 'rb+wb', 0) # open file in an unbuffered mode _make_non_blocking(master) prog = subprocess.Popen(shell=False, args=['/bin/sh', '-i'], stdin=slave, stdout=slave, stderr=subprocess.STDOUT, preexec_fn=prepare)