【发布时间】:2014-12-21 17:40:53
【问题描述】:
我试图了解 Python 的 subprocess 模块是如何工作的,并开始给自己设置一些不像我想象的那么简单的问题。具体来说,我正在尝试与作为子进程创建的 Python 解释器进行交互。
我创建了一个测试模块dummy.py,其结构如下:
def hi():
print "Hi Earth"
hi()
然后,为了测试我使用 subprocess 模块的能力,我编写了一个名为 pyrun.py 的模块,其结构如下:
import subprocess
def subprocess_cmd1():
outFile = open("tempy1.tmp",'w')
proc = subprocess.Popen("pwd", stdin=subprocess.PIPE, stdout=outFile, stderr=outFile, shell=True)
outFile.close()
def subprocess_cmd2():
outFile = open("tempy2.tmp",'w')
proc = subprocess.Popen('python dummy.py', stdin=subprocess.PIPE, stdout=outFile, stderr=outFile, shell=True)
outFile.close()
def subprocess_cmd3():
outFile = open("tempy3.tmp",'w')
proc = subprocess.Popen('python', stdin=subprocess.PIPE, stdout=outFile, stderr=outFile, shell=True)
proc.communicate('import dummy')
outFile.close()
def subprocess_cmd4():
outFile = open("tempy4.tmp",'w')
proc = subprocess.Popen('python', stdin=subprocess.PIPE, stdout=outFile, stderr=outFile, shell=True)
proc.communicate('import dummy')
proc.communicate('dummy.hi()')
outFile.close()
print "Start"
subprocess_cmd1()
subprocess_cmd2()
subprocess_cmd3()
subprocess_cmd4()
print "Stop"
想法是将输入从调用进程发送到子进程,并将所有输出发送到文本文件。
当我尝试从命令行运行 pyrun 时,我得到以下结果:
me@Bedrock1:~/Projects/LushProjects/newCode$ python pyrun.py
Start
Traceback (most recent call last):
File "pyrun.py", line 42, in <module>
subprocess_cmd4()
File "pyrun.py", line 35, in subprocess_cmd4
proc.communicate('dummy.hi()')
File "/usr/lib/python2.7/subprocess.py", line 785, in communicate
self.stdin.write(input)
ValueError: I/O operation on closed file
subprocess_cmd1 - 3 运行时不会崩溃。尝试执行语句时,subprocess_cmd4() 出现错误:
proc.communicate('dummy.hi()')
这似乎是因为communicate 方法在首次使用后将管道关闭到stdin。为什么这样做?假设管道应该关闭有什么好处吗?
此外,当我查看 tempy3.tmp 的内容(subprocess_cmd3 的输出文件)时,它缺少 Python 解释器的“开始”文本 - 即
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
这是为什么呢?我将 both stdout 和 stderr 重定向到 outFile。
最后,为什么tempy4.tmp 完全是空的?它不应该至少包含崩溃前发送给它的文本吗? (即它应该看起来很像tempy3.tmp)
【问题讨论】:
-
无关:为什么要使用 subprocess 来运行 Python 代码?
-
@J.F.Sebastien - 我真的只是在尝试子流程,看看我是否了解如何使用它以及它是如何工作的。我想一个更现实的例子是使用它在其他语言的解释器中运行代码。
-
如果它是一个学习练习,那么这里有一些提示: 1. 避免
shell=True,使用列表参数来传递命令 2. 知道如果子进程的 stdin/ 子进程可能表现不同stdout/stderr 被重定向(例如,抑制输出中的颜色(ansi 代码))或没有标题,如python的情况。 -
3.了解缓冲问题(这里是a simple case where the parent only reads child's output):在孩子看到
p.stdin.write("import dummy\n")数据之前有几个缓冲区。 4.子进程可以read/write directly to terminal。给定 pp.3 和 4(用于基于对话的交互)pexpectcan be more convienient。 5.you don't need multiple threads or multiprocessing to run several subprocesses in parallel
标签: python python-2.7 subprocess