【发布时间】:2017-02-07 01:55:23
【问题描述】:
我正在尝试使用子进程在 python 中以交互方式运行 python。当我运行以下脚本时,它会挂在我从 stderr 读取的内容上。
import subprocess
p = subprocess.Popen('python', shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stdin=subprocess.PIPE,
bufsize=1, universal_newlines=True)
text = p.stderr.read(256)
p.stdin.write('exit()\n')
p.close()
但是,如果我进行微小的更改以从构造函数中删除 stdin=subproces.PIPE,它会成功运行,并且 text 被分配来自 p.stderr 的输出,然后在 p.stdin.write(..) 上使用 @987654327 失败@
为什么会挂起?我正在尝试保持一个子进程打开以随意读取和写入。
我想做这个单线程。我的“主”脚本打开 python,然后运行一个循环,该循环从用户那里获取输入。如果用户输入'r',它会从进程中读取,如果他们输入'w',它会写入进程。
我搜索的越多,测试不同的解决方案的次数越多,似乎就不可能使用 python 子进程同时管道输入和输出流。如果我没有传入 stdin=PIPE,我可以正常运行程序并读取 stderr。我也尝试为每个文件指针使用不同的命名文件,但没有成功。
仍在打这场仗。就像一个注释,如果其他人熟悉 ruby 世界,我想做的事情可以使用“ChildProcess”gem。 python一定有办法
【问题讨论】:
-
我建议使用
p.communicate()而不是直接写入标准输入,这总是容易出现死锁。但是,我看不出这会有什么用。 -
p.communicate() 块。我没有进入 stdin 调用,因为它阻塞了对 stderr.read 的调用,尽管输出可用。
-
python 版本之间的工作方式有很多不同。或者至少以前是这样。你正在运行什么版本的python,你正在运行什么进程? docs.python.org/2/library/…
-
您应该删除对 stderr.read() 的调用。而且我认为没有可用的输出。如果 Python 的标准输入连接到管道,则 Python 不会打印版权声明。
-
您无需深入研究源代码。只需阅读 Python 的手册页就足够了。您还可以从 bash shell 运行
python <<< ""并验证它不打印任何内容。在非交互模式下,Python 会在编译之前读取整个输入,所以它不会做你想做的事。如果你想执行 Python 代码,当前的解释器就可以了。在子进程中不需要第二个。您可能希望使用exec语句并传入单独的全局命名空间,具体取决于您的用例。
标签: python-2.7 subprocess