Python - 对关闭文件的子进程I/O操作
我用下面这个类尝试过,在Python 2.6中用subprocess模块按顺序执行命令。
from subprocess import Popen, PIPE
class BaculaActions():
def __init__(self):
self.console = Popen(["bconsole"], stdout=PIPE, stderr=PIPE, stdin=PIPE)
def run_job(self, jobname, level):
run = self.console.communicate("run job=%s level=%s yes" % (jobname, level))
return(run)
def del_jobid(self, jobid):
delete = self.console.communicate("delete jobid=%s" % (jobid))
return(delete)
但是,如果我尝试以下代码,就会出现错误: ValueError: 在关闭的文件上进行I/O操作。
from pconsole import BaculaActions
myconsole = BaculaActions()
run = myconsole.run_job("xxxxx-data", "incremental")
delete = myconsole.del_jobid(25487)
有人知道可能出什么问题了吗? 谢谢!
3 个回答
-2
更好的做法是这样:
任何子进程的初始化都应该用“try catch”来包裹,这样可以处理资源分配失败的情况。如果成功了,就返回结果。
在进行通信之前,先检查一下通道是否已经建立(没有错误),然后再进行通信。
最好的方法是把“Popen”放在你进行通信的同一个地方。这样可能会导致你重复使用“Popen”两次,但这样做是安全的。
在“Popen”和“communicate”之间,如果出现任何未知的中断,可能会导致你的Python程序一直挂着,需要手动结束。这是我们在实际操作中绝对不想发生的情况。
1
感谢所有曾经尝试帮助我的人。
作为解决这个问题的方法,我做了以下事情:
class BaculaActions():
def console(self):
return(Popen(["bconsole"], stdout=PIPE, stderr=PIPE, stdin=PIPE))
def run_job(self, jobname, level):
run = self.console().communicate("run job=%s level=%s yes" % (jobname, level))
return(run)
def del_jobid(self, jobid):
delete = self.console().communicate("delete jobid=%s" % (jobid))
return(delete)
def any_commands(self, command):
any = self.console().communicate(command)
return(any)
我创建了一个叫“console”的方法,然后在我的类中的其他所有方法开始时都调用这个方法。
这样就解决了我的问题。
谢谢大家!
5
手册上其实说得很清楚:
Popen.communicate(input=None, timeout=None)
Interact with process: Send data to stdin. Read data from stdout and stderr,
until end-of-file is reached. Wait for process to terminate.
当你运行第一个命令并得到结果后,'bconsole'这个过程就已经结束了,管道也关闭了,所以在第二次调用communicate
时就会出现错误。