用popen无法启动两个交互shell [英] Cannot start two interactive shells using popen

查看:301
本文介绍了用popen无法启动两个交互shell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的Python代码片段,并不能解释为什么它的行为方式是这样。

 导入子
bash1 = subprocess.Popen([/斌/ bash的, - 1,-i],标准输入= subprocess.PIPE)
打印检查点1
bash2 = subprocess.Popen([/斌/ bash的, - 1,-i],标准输入= subprocess.PIPE)
打印检查点2
bash1.communicate(回声works1')
bash2.communicate(回声Works2的')
打印OK

当我运行它,我得到以下的输出:

  [用户@本地〜] $蟒蛇test.py
检查点1
检查点2
[1] +停止蟒蛇test.py
[用户@本地〜] $ [用户@本地〜] $回声'works1
works1
[用户@本地〜] $注销
[用户@本地〜] $ FG
蟒蛇test.py
[用户@本地〜] $回声'Works2的
Works2的
[用户@本地〜] $注销

[用户@本地〜] $


  1. 为什么Python的过程中停止了对第二POPEN电话吗? (由TTY输入停止),以及如何避免呢?

  2. 为什么我收到注销邮件回声works1'结束后,以及如何避免呢?


解决方案

答问题1:

这是因为一个交互式bash外壳期望要附加到​​一个端子('控制终端')和以处理作业控制的中断(例如控制-Z)获得它。第二次调用试图获取终端却不能,因此被暂停。

答问题2:

沟通将它的参数传递给子进程的标准输入管道,然后将其关闭。当它的标准输入耗尽击结束(这就像在一个bash终端会话进入控制-D)。

如果你想保持bash的子进程的运行,然后写入其标准输入,而不是直接使用沟通如下:

  bash1.stdin.write(回声works1的'\\ n)

您确实需要添加新行,如果你想命令实际执行,顺便说一句。

一个解决方案:

如果你想运行两个或更多的交互式shell,你应该设置每个壳的标准输入是一个的伪终端,而不是一个子进程管道。

I have the following Python snippet, and cannot explain why it behaves the way it does.

import subprocess  
bash1 = subprocess.Popen(["/bin/bash","-l", "-i"], stdin=subprocess.PIPE)  
print "Checkpoint 1"  
bash2 = subprocess.Popen(["/bin/bash","-l", "-i"], stdin=subprocess.PIPE)  
print "Checkpoint 2"  
bash1.communicate("echo 'works1'")  
bash2.communicate("echo 'works2'")  
print "OK"

When I run it, I get the following output:

[user@localhost ~]$ python test.py  
Checkpoint 1  
Checkpoint 2  
[1]+  Stopped                 python test.py
[user@localhost ~]$ [user@localhost ~]$ echo 'works1'  
works1  
[user@localhost ~]$ logout  
[user@localhost ~]$ fg    
python test.py  
[user@localhost ~]$ echo 'works2'  
works2  
[user@localhost ~]$ logout 
OK  
[user@localhost ~]$

  1. Why is Python process stopped on second Popen call? (stopped by tty input), and how to avoid it?
  2. Why do I get logout message after echo 'works1' is finished, and how to avoid it?

解决方案

Answer to question 1:

This is because an interactive bash shell expects to be attached to a terminal (the 'controlling terminal') and acquire it in order to process job control interrupts (e.g. Control-Z). The second invocation tries to acquire the terminal but can't, so gets temporarily suspended.

Answer to question 2:

communicate writes its argument to the stdin pipe of the child process and then closes it. Bash terminates when its stdin is exhausted (it is like entering Control-D in a bash terminal session).

If you want to keep the bash child process running, then write to its stdin directly rather than use communicate as follows:

bash1.stdin.write("echo 'works1'\n")

You do need to add the newline if you want the command to actually execute, by the way.

A solution:

If you want to run two or more interactive shells, you should setup the stdin of each shell to be a pseudo-terminal rather than a subprocess PIPE.

这篇关于用popen无法启动两个交互shell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆