Python -对已关闭文件进行子进程I/O操作

时间:2021-05-15 20:27:20

I have tried with the class below, execute commands in sequence with subporcess module in python2.6.

我尝试了下面的类,使用python2.6中的subporcess模块按顺序执行命令。

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)

However, if I try the following code, I get the error: ValueError: I / O operation on closed file

但是,如果我尝试以下代码,就会得到错误:ValueError:封闭文件上的I / O操作

from pconsole import BaculaActions

myconsole = BaculaActions()

run = myconsole.run_job("xxxxx-data", "incremental")
delete = myconsole.del_jobid(25487)

Anyone have idea what can be wrong? I thank

有人知道有什么不对劲吗?我感谢

3 个解决方案

#1


5  

The manual says it all really:

手册上说的都是:

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.

After you run the first command and get the result, the 'bconsole' process has terminated, the pipes are closed and hence the error on the second communicate call.

在运行第一个命令并得到结果之后,“bconsole”进程终止,管道关闭,因此第二次通信调用出现错误。

#2


0  

Thanks to everyone who somehow tried to help me. As a solution to the problem, I made the following:

感谢每一个试图帮助我的人。为了解决这个问题,我做了以下几点:

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)

I created a method "console" and all other methods of my class I start.

我创建了一个方法“控制台”和我开始的类的所有其他方法。

This solved my problem.

这解决了我的问题。

Thank you

谢谢你!

#3


-1  

Better way is to do as below,

更好的方法是做下面这些,

Any sub process initialization must be encapsulated with try catch, to handle resource allocation failures. Then return it, if success.

任何子进程初始化都必须使用try catch进行封装,以处理资源分配失败。如果成功了,就把它还给我。

Before communicating, check whether channel is established (no errors) then communicate.

在通信之前,检查是否建立了通道(没有错误),然后进行通信。

Best way is to keep "Popen" on the same place whereever you communicate.You may end up duplicating "Popen" two times. But this is safe.

最好的办法就是把“Popen”放在你交流的地方。你可能会重复两次“Popen”。但这是安全的。

Any unknown interrupts between “Popen” and “communicate”, will make your python job as hanging forever and will need manual kill. This is certainly what we don’t want in live

在“Popen”和“communication”之间的任何未知中断,都将使您的python工作永远挂起,并且需要手动终止。这当然是我们生活中不需要的

#1


5  

The manual says it all really:

手册上说的都是:

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.

After you run the first command and get the result, the 'bconsole' process has terminated, the pipes are closed and hence the error on the second communicate call.

在运行第一个命令并得到结果之后,“bconsole”进程终止,管道关闭,因此第二次通信调用出现错误。

#2


0  

Thanks to everyone who somehow tried to help me. As a solution to the problem, I made the following:

感谢每一个试图帮助我的人。为了解决这个问题,我做了以下几点:

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)

I created a method "console" and all other methods of my class I start.

我创建了一个方法“控制台”和我开始的类的所有其他方法。

This solved my problem.

这解决了我的问题。

Thank you

谢谢你!

#3


-1  

Better way is to do as below,

更好的方法是做下面这些,

Any sub process initialization must be encapsulated with try catch, to handle resource allocation failures. Then return it, if success.

任何子进程初始化都必须使用try catch进行封装,以处理资源分配失败。如果成功了,就把它还给我。

Before communicating, check whether channel is established (no errors) then communicate.

在通信之前,检查是否建立了通道(没有错误),然后进行通信。

Best way is to keep "Popen" on the same place whereever you communicate.You may end up duplicating "Popen" two times. But this is safe.

最好的办法就是把“Popen”放在你交流的地方。你可能会重复两次“Popen”。但这是安全的。

Any unknown interrupts between “Popen” and “communicate”, will make your python job as hanging forever and will need manual kill. This is certainly what we don’t want in live

在“Popen”和“communication”之间的任何未知中断,都将使您的python工作永远挂起,并且需要手动终止。这当然是我们生活中不需要的