python子进程中stdout的损坏文件

时间:2014-04-26 11:10:42

标签: python subprocess stdout

我想编写一个python脚本,它从一系列作业中运行几个c ++程序。

我认为它工作正常,但我的输出文件有问题,似乎是损坏的东西。无论如何我无法打开它们。也许你们可以帮助我。

import multiprocessing
import psutil
import subprocess
import time

jobs2Do = True

while (jobs2Do):    #Ever-running program

cpuLoad = cpuLoad + psutil.cpu_percent()

if (cpuLoad < 90):
    with open('JobQueue.txt', 'r') as f:
        first_line = f.readline()
        path = f.readline()
        f.close()
    if (first_line != ""):
        print "Opening " + first_line
        process = subprocess.Popen( first_line, shell=True, stdout=open(path,"w"),stderr=open("error.log","w"))

        with open('JobQueue.txt', 'r') as fin:
            data = fin.read().splitlines(True)
        with open('JobQueue.txt', 'w') as fout:
            fout.writelines(data[2:])
        with open("JobsDone.txt", "a") as myfile:
            myfile.write(first_line)
            myfile.write(path)
        myfile.close()

    else:
        print "No more jobs... waiting for new jobs...."
        time.sleep(10)

好吧,我(想)做的是:我检查一下,如果cpu有一些空闲容量,如果是这样,用作业打开文件并获取命令,该命令位于该文件的第一行,以及保存程序所有输出的路径。这始终位于文件的第二行。

然后我想打开那个子进程,并将stdout放到我的优先路径并将errorstream放到任何地方。最后,我从列表中删除了该作业,并从头开始。

我现在的问题是,stdout = open(路径,&#34; w&#34;)似乎有点腐败,因为我无法访问甚至删除它,但我可以看到它在文件夹中。

也许你们有个主意,我做错了什么。

感谢您的努力!

NonStopAggroPop

PS:也许我还应该补充一点,c ++程序运行的时间更长。所以我有意想做的就是让程序执行nohup ./c++ [arguments]并将输出流式传输到特定文件,就像我在控制台中输入它一样。

PPS:我希望能够启动多个c ++程序,而其他程序仍在运行,直到我的cpu达到100%的使用率。

1 个答案:

答案 0 :(得分:1)

  

我现在的问题是,stdout=open(path,"w")似乎有点腐败,因为我无法访问甚至删除它,但我可以在文件夹中看到它。

问题是path = f.readline()在结尾处返回带有换行符的字符串。某些系统上的open(path, 'w')不关心并在最后创建带换行符的文件。请尝试print(os.listdir('.'))查看文件名中的\n

要解决此问题,只需删除换行符:path = path.strip()


您的代码中还有其他无关的问题:

  • 您正在混合标签和空格以进行缩进。永远不要这样做:它使视觉缩进不同于Python目前在你的问题中所看到的。要么总是使用制表符或空格,要么两者都使用。您可以将编辑器配置为在按Tab键时插入4个空格。

  • 你可能意味着cpuLoad = psutil.cpu_percent()而不是cpuLoad = cpuLoad + psutil.cpu_percent(),无缘无故地增加了循环的每次迭代

  • 从命令中删除换行符并删除shell=True。除非有必要,否则不要使用shell(如果你知道自己在做什么,这种习惯有时会被打破):

    import shlex
    
    process = Popen(shlex.split(command),
                    stdout=output_file, stderr=stderr_file)
    
  • 使用with - 代码语句与其他Python实现兼容,如Jython,Pypy:

    with open(path, 'w') as output_file:
         with open('error.log', 'w') as stderr_file:
             process = Popen(shlex.split(command),
                             stdout=output_file, stderr=stderr_file)
    

    否则文件可能在父进程中保持打开状态。

  • f.close()之后删除myfile.close()with - 关闭 文件本身,即使发生了它的目的,它的例外 raison d'être。 .close()在这方面是无害的,但毫无意义 情况下

  • 使用if not first_line.strip():来测试第一行是否为空(仅包含空格)

  • 手动编辑JobQueue.txt的整个想法很脆弱。没有什么能阻止Python进程只读取部分输入。您可以使用专用命令添加新作业,例如at - 就像实用程序一样。然后按照你喜欢的方式实现它,例如,在一个端口上监听主脚本中的新作业,并在at中发送作业 - 就像实用程序一样。这是the very basic socket client and server in Python的代码示例。或者使用其他IPC方法。