from subprocess import Popenprocess = Popen( ["/bin/bash"],stdin=sys.stdin,stdout=sys.stdout,stderr=sys.stderr,)process.wait()
我可以交互式地使用bash,tab works等.
但是,我想控制我发送到stdin的内容,所以我希望以下工作:
import osimport sysfrom subprocess import Popen,PIPEfrom select import selectprocess = Popen( ["/bin/bash"],stdin=PIPE,)while True: if process.poll() is not None: break r,_,_ = select([sys.stdin],[],[]) if sys.stdin in r: stdin = os.read(sys.stdin.fileno(),1024) # Do w/e I want with stdin os.write(process.stdin.fileno(),stdin)process.wait()
但这种行为并不相同.我尝试了另一种方法(通过pty):
import osimport sysimport ttyfrom subprocess import Popenfrom select import selectmaster,slave = os.openpty()stdin = sys.stdin.fileno()try: tty.setraw(master) ttyname = os.ttyname(slave) def _preexec(): os.setsID() open(ttyname,"r+") process = Popen( args=["/bin/bash"],preexec_fn=_preexec,stdin=slave,close_fds=True,) while True: if process.poll() is not None: break r,[]) if sys.stdin in r: os.write(master,os.read(stdin,1024))finally: os.close(master) os.close(slave)
并且行为非常接近,除了tab仍然不起作用.好吧,tab已正确发送,但我的终端没有显示完成,即使它是由bash完成的.箭头也显示^ [[而不是通过历史记录.
任何的想法?
解决方法 我只需要将我的sys.stdout设置为raw.我还发现了3件事:>我需要恢复sys.stdout上的终端设置
> subprocess.Popen有一个start_new_session参数,它执行我的_preexec函数正在执行的 *** 作.
> select.select接受第4个参数,这是放弃之前的超时.它让我避免在退出后卡在选择循环中.
最终代码:
import osimport sysimport ttyimport termiosimport selectimport subprocessmaster,slave = os.openpty()stdin = sys.stdin.fileno()try: old_settings = termios.tcgetattr(sys.stdout) tty.setraw(sys.stdout) process = subprocess.Popen( args=["/bin/bash"],start_new_session=True,_ = select.select([sys.stdin],0.2) if sys.stdin in r: os.write(master,1024))finally: termios.tcsetattr(sys.stdout,termios.TCSADRAIN,old_settings) os.close(master) os.close(slave)总结
以上是内存溢出为你收集整理的python – 如何使用`stdin = PIPE`重现`stdin = sys.stdin`?全部内容,希望文章能够帮你解决python – 如何使用`stdin = PIPE`重现`stdin = sys.stdin`?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)