如何运行在单独的进程壳获得自动补全? (蟒蛇) [英] How to run a shell in a separate process and get auto completions? (Python)
问题描述
我有一个Linux应用程序,从某些设备获取的输入流。因此,它模拟给用户一个标准的外壳,输入应被定向到一个shell进程。到目前为止,我已经通过创建运行/ bin / sh的'一个过程来完成它,我重定向其输入,输出和标准错误如下:
导入子P = subprocess.Popen(SHELL =假,ARGS = ['/ bin / sh的'],标准输入= subprocess.PIPE,标准输出= subprocess.PIPE,标准错误= subprocess.PIPE)
_make_nonblocking(p.stdout)#台O_NONBLOCK
_make_nonblocking(p.stderr)
当我刚一通命令,一切正常:
p.stdin.write('PWD \\ n)
p.stdout.read()
'/家庭/戴夫\\ n'
有关自动完成,我试着写:
p.stdin.write('LS小号\\ T')
p.stdout.read()
IO错误:[错误11]资源暂时不可用
我希望得到尽可能完整的列表,但没有任何反应,直到我把'\\ n'的标准输入。 (另外,没有任何等待标准错误)。
我已经通过telnetd的code望去,只见使用pty的。我试图用pty.openpty(),并设置从作为标准输入,但也不能工作。应如何做?
更新:我用-i参数的建议。现在我有,一旦我使用POPEN和preSS ENTER蟒蛇的外壳移动到背景如下问题:
>>> P = subprocess.Popen(SHELL =假,ARGS = ['/ bin / sh的','-i'],标准输入= subprocess.PIPE,标准输出= subprocess.PIPE,标准错误= subprocess.PIPE)
>>> <&ENTER GT;
[1] +停止IPython中
$
最终彻底解决所有的问题,我不得不做几件事情:
- 配置pty设备(使用python的PTY模块)。
- 将使用termios的相应标志(回声,信号处理等)。
- 启动一个新的会话(这样的信号不会propagte原工艺)。
- 使用无缓冲文件(BUFSIZE传球0)打开pty设备。
这是code的作品:
DEF prepare():
os.setsid()#启动一个新的独立的会话
tty.setcbreak(sys.stdin)#设置标准输入模式CBREAK
老= termios.tcgetattr(sys.stdin)
老[0] | = termios.BRKINT#转换为突破SIGINT
老[3]和安培; =#termios.ICANON非标准模式
老[3] | = termios.ECHO | termios.ISIG#设置回音和信号处理的字符
CC =旧[6]
#使输入缓冲
立方厘米[termios.VMIN] = 1
立方厘米[termios.VTIME] = 0
termios.tcsetattr(sys.stdin,termios.TCSANOW,老)主,从= pty.openpty()
主= os.fdopen(主人,RB + WB',0)#打开文件中的缓冲模式
_make_non_blocking(主)PROG = subprocess.Popen(SHELL =假,ARGS = ['/ bin / sh的','-i'],标准输入=奴隶,标准输出=奴隶,标准错误= subprocess.STDOUT,preexec_fn = prepare)
I have a linux application that gets an input stream from some device. That input should be directed to a shell process so that it emulates to the user a standard shell. So far, I've done it by creating a process that runs '/bin/sh' and I redirected its input, output, and stderr as follows:
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)
When I just a pass command, everything works:
p.stdin.write('pwd\n')
p.stdout.read()
'/home/dave\n'
For auto completion, I tried writing:
p.stdin.write('ls s\t')
p.stdout.read()
IOError: [Errno 11] Resource temporarily unavailable
I expect to get a list of possible completions but nothing happens until I put '\n' in stdin. (Also, there was nothing waiting in stderr).
I've looked through the telnetd code and saw the use of pty. I tried to use pty.openpty() and set slave as stdin, but that didn't work either. How should it be done?
UPDATE: I used the -i parameter as suggested. Now I have a problem that once I use Popen and press ENTER the python shell move to the background as follows:
>>> p = subprocess.Popen(shell=False, args=['/bin/sh', '-i'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> <ENTER>
[1]+ Stopped ipython
$
Eventually to completely solve all problems I had to do several things:
- configure a pty device (using pty module in python).
- set the appropriate flags using termios (echo, signal handling, etc).
- start a new session (so that signals won't propagte the original process).
- open the pty device using an unbuffered file (passing 0 in bufsize).
This is the code that works:
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)
这篇关于如何运行在单独的进程壳获得自动补全? (蟒蛇)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!