简体   繁体   English

python子进程中stdout的损坏文件

[英]Corrupt file for stdout in python subprocess

i wanted to program a python script which runs several c++ programs from a list of jobs. 我想编写一个Python脚本,该脚本从作业列表中运行多个c ++程序。

I think it works fine, but i have a problem with the output file, which seems to be damaged or something. 我认为它工作正常,但是我的输出文件有问题,似乎已损坏或发生了什么。 Anyways i can't open them. 无论如何,我无法打开它们。 Maybe you guys can help me. 也许你们可以帮我。

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)

Okay, so what i (want to) do is: I check, if the cpu has some free capacities, if so, open the file with the jobs and get the command, which is in the first line of that file, and the path to where all the output of the program should be saved to. 好的,所以我想做的是:检查CPU是否具有一些可用容量,如果有,请用作业打开文件并获取命令,该命令位于该文件的第一行以及路径中。程序所有输出应保存到的位置。 This is always in the second line of the file. 它始终位于文件的第二行。

Then I want to open that subprocess, and put the stdout to my preffered path and put the errorstream to wherever. 然后,我想打开该子进程,并将stdout放到我的首选路径中,并将错误流放到任何地方。 Finally, I delete the job from the list and start from the beginning. 最后,我从列表中删除作业,然后从头开始。

My Problem now is, that the stdout=open(path,"w") seems to be sort of corrupt, because I can't access or even delete it, but I can see it in the folder. 我的问题现在是,stdout = open(path,“ w”)似乎已损坏,因为我无法访问甚至删除它,但可以在文件夹中看到它。

Maybe you guys have an idea, what I did wrong. 也许你们有个主意,我做错了什么。

Thanks for your effort! 谢谢你的努力!

NonStopAggroPop NonStopAggroPop

PS: Maybe I should also add, that the c++-programs are running for a longer period of time. PS:也许我还应该补充一点,C ++程序运行时间更长。 So what I intentionally wanted to do is just let the program execute nohup ./c++ [arguments] and stream the output to a specific file, like it would if I typed it in the console. 因此,我有意要做的就是让程序执行nohup ./c++ [arguments]并将输出流式传输到特定文件,就像在控制台中键入该文件一样。

PPS: And I want to be able to start multiple c++-programs while the others are still runing, until my cpu reaches 100% usage. PPS:我希望能够在其他C ++程序仍在运行时启动多个c ++程序,直到我的cpu达到100%使用率为止。

My Problem now is, that the stdout=open(path,"w") seems to be sort of corrupt, because I can't access or even delete it, but I can see it in the folder. 我的问题现在是, stdout=open(path,"w")似乎已损坏,因为我无法访问甚至删除它,但可以在文件夹中看到它。

The issue is that path = f.readline() return a string with a newline at the end. 问题是path = f.readline()返回结尾处带有换行符的字符串。 open(path, 'w') on some systems doesn't care and creates the file with a newline at the end. 某些系统上的open(path, 'w')无关紧要,并在文件末尾添加换行符。 Try print(os.listdir('.')) to see \\n in the filename. 尝试使用print(os.listdir('.'))在文件名中看到\\n

To fix it, just remove the newline: path = path.strip() . 要解决此问题,只需删除换行符: path = path.strip()


There are other unrelated issues in your code: 您的代码中还有其他不相关的问题:

  • you are mixing tabs and spaces for indentation. 您正在混合制表符和空格以进行缩进。 Never do that: it makes the visual indentation different from the one Python sees as it currently is in your question. 永远不要那样做:它使视觉缩进不同于您当前在问题中所看到的那种。 Either always use tabs or spaces, not both. 请始终使用制表符或空格,而不要同时使用两者。 You can configure your editor to insert 4 spaces when you hit Tab key. 您可以将编辑器配置为在按Tab键时插入4个空格。

  • you probably meant cpuLoad = psutil.cpu_percent() instead of cpuLoad = cpuLoad + psutil.cpu_percent() that increases each iteration of the loop for no reason 您可能是说cpuLoad = psutil.cpu_percent()而不是cpuLoad = cpuLoad + psutil.cpu_percent()cpuLoad = cpuLoad + psutil.cpu_percent()增加循环的每次迭代

  • remove the newline from the command and remove shell=True . 从命令中删除换行符,然后删除shell=True Don't use shell unless it is necessary (it is a good habit that sometimes may be broken if you know what you are doing): 除非必要,否则不要使用shell(这是一个好习惯,如果您知道自己在做什么,有时可能会被破坏):

     import shlex process = Popen(shlex.split(command), stdout=output_file, stderr=stderr_file) 
  • use with -statements for the code to be compatible with other Python implementations such as Jython, Pypy: with -statement一起使用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) 

    otherwise the files may remain open in the parent process. 否则文件可能在父进程中保持打开状态。

  • remove f.close() , myfile.close() after the with -statement that closes the file by itself even if an exception occurs that is its purpose, its raison d'être. 使用f.close()删除f.close()myfile.close()之后, with自行关闭文件,即使发生异常是其目的,即存在的理由。 .close() is harmless but pointless in this case .close()是无害的,但在这种情况下毫无意义

  • use if not first_line.strip(): to test whether the first line is blank (contains only whitespace) if not first_line.strip():使用if not first_line.strip():测试第一行是否为空白(仅包含空白)

  • the whole idea of manually editing JobQueue.txt is fragile. 手动编辑JobQueue.txt的整个想法很脆弱。 Nothing stops Python process to read only partial input. 没有什么能阻止Python进程仅读取部分输入。 You could use a dedicated command to add new jobs eg, at -like utility. 您可以使用专用命令来添加新作业,例如at -like实用程序。 And implement it however you like eg, listen on a port for a new jobs in the main script and send jobs in at -like utility. 并根据自己的喜好实现它,例如,在主脚本中侦听端口上的新作业,然后at -like实用程序中发送作业。 Here's a code example of a the very basic socket client and server in Python . 这是Python中非常基本的套接字客户端和服务器的代码示例。 Or use other IPC methods. 或使用其他IPC方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM