循环中只有第一个subprocess.Popen(...,stdin = f)可以正常工作 [英] Only first subprocess.Popen(..., stdin=f) in a loop works correctly

查看:198
本文介绍了循环中只有第一个subprocess.Popen(...,stdin = f)可以正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里的主要目标是获取与Linux连接的计算机列表的所有cpu费用.我已经在网上挣扎了一段时间,但由于找不到答案,我必须错过一些东西. 所以我定义了一个cpu_script.py:

My main goal here is to get all the cpu charge of a list of Linux-connected computers. I have been struggling and searching on the net for some time but I must miss something as I can't find my answer. So I defined a cpu_script.py :

import psutil

print(psutil.cpu_percent(interval=1,percpu=True))

在我的主脚本(位于同一文件夹中)中被调用,

to be called in my main script, which is in the same folder, with:

import subprocess
import os
import numpy as np
import psutil

usr = "AA"
computer = ["c1", "c2", "c3"] #list of computer which cpu load is to be tested
cpu_script = os.path.join(os.getcwd(),"cpu_script.py")

with open(cpu_script,"rb") as f:
    for c in computer:
        input(c)
        process = subprocess.Popen(["ssh","-X",usr + "@" + c,"python3","-u","-"], stdin=f, stdout=subprocess.PIPE)
        out = process.communicate()[0]
        input(out)

现在这是我从这些input中得到的内容:

Now here is what I got from these input :

>> c1 #first computer
>> <subprocess.Popen object at 0x7fd210aab358>
>> b'[1.0, 7.1, 0.0, 1.0, 2.0, 2.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0]\n'
>> c2 #second computer
>> <subprocess.Popen object at 0x7fd210aab390>
>> b''
>> c3 #third computer
>> <subprocess.Popen object at 0x7fd210aab390>
>> b''

这是我的问题:为什么第二个和第三个输出为空?我怎么能得到他们?

So here is my question : why are the second and third output empty ? How could I get them ?

我怀疑我的第一个过程未很好地关闭",因此我尝试在input(out)之后添加process.wait()process.kill(),但无济于事.

I suspected that my first process was not well "closed", so I tried to add a process.wait() or a process.kill() just after the input(out), but to no avail.

在此先感谢您的帮助!

subprocess.check_output()给出相同的输出.我也尝试使用subprocess.run:

edit: subprocess.check_output() gives the same outputs. I also tried subprocess.run with:

with open(cpu_script,"rb") as f:
    for c in computer:
        input(c)
        process = subprocess.run(["ssh","-X",usr + "@" + c,"python3","-u","-"], stdin=f, stdout=subprocess.PIPE)
        input(out)

并得到:

>> c1 #first computer
>> CompletedProcess(args=['ssh', '-X', 'usr@c1', 'python3', '-u', '-'], returncode=0, stdout=b'[2.0, 1.0, 1.0, 2.9, 7.0, 0.0, 2.0, 1.0, 0.0, 0.0, 0.0, 1.0]\n')
>> c2 #second computer
>> CompletedProcess(args=['ssh', '-X', 'usr@c2', 'python3', '-u', '-'], returncode=0, stdout=b'')
>> c3 #third computer
>> CompletedProcess(args=['ssh', '-X', 'usr@c3', 'python3', '-u', '-'], returncode=0, stdout=b'')

推荐答案

这里的问题是,一旦您的文件被读取一次,指针就位于文件的末尾,因此没有什么可读取的(所以第二个当您为同一文件传递stdin=f时,剩下的只是空白).

The problem here is that once your file has been read once, the pointer is at the end of the file, so there's nothing left to read (so the second time you pass stdin=f for the same file, what's left is just empty).

每次要使用该文件时,请反转内部和外部循环以重新打开该文件:

Invert your inner and outer loops to reopen the file once every time you want to use it:

for c in computer:
    with open(cpu_script, "rb") as f:
        process = subprocess.Popen(["ssh", "-X", "-l", usr, c, "python3 -u -"],
                                   stdin=f, stdout=subprocess.PIPE)
        out = process.communicate()[0]

...或使用seek()函数返回到内部循环之间的开头:

...or rewind back to the beginning between inner loops using the seek() function:

with open(cpu_script, "rb") as f:
    for c in computer:
        f.seek(0)   ### <- THIS RIGHT HERE
        process = subprocess.Popen(["ssh", "-X", "-l", usr, c, "python3 -u -"],
                                   stdin=f, stdout=subprocess.PIPE)
        out = process.communicate()[0]

这篇关于循环中只有第一个subprocess.Popen(...,stdin = f)可以正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆