如何运行在单独的进程壳得到自动完成功能? (蟒蛇)(How to run a shell in

2019-09-21 18:25发布

我有一个Linux应用程序,从某个设备获得的输入流。 使得它模拟给用户的标准外壳,输入应被定向到一个外壳进程。 到目前为止,我已经通过创建运行“/ bin / sh的”一个过程来完成它,我重定向它的输入,输出和标准错误如下:

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”的标准输入。 (另外,没有任何等待标准错误)。

我已经通过telnetd的代码望去,只见使用pty的。 我试图用pty.openpty()和从属组作为标准输入,但也不能工作。 应该怎样做呢?

更新:我使用-i参数的建议。 现在我有,一旦我使用POPEN,然后按ENTER蟒蛇的外壳移动到背景如下问题:

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

Answer 1:

随着bash自动完成功能只能在交互模式:

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

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



Answer 2:

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

  1. 配置PTY设备(使用PTY模块在python)。
  2. 设定使用的termios(回波,信号处理等)相应的标志。
  3. 启动一个新的会话(使信号不会propagte原工艺)。
  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)


文章来源: How to run a shell in a separate process and get auto completions? (Python)