subprocess 和 psutil:如何从 subprocess.check_output 中获取列表?

subprocess and psutil : how to get a list out of subprocess.check_output?

我愿意确定一堆 Linux 计算机的当前 CPU 使用情况,所有这些计算机都可以通过 SSH 连接使用。至于现在,我已经通过 psutil 和 subprocess 模块管理了一些东西,但如果我能从 subprocess.check_output 中得到一个列表,它可能会更直接。

所以我定义了一个cpu_script.py :

import psutil

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

在我的主脚本中调用,它在同一个文件夹中,与:

import subprocess
import os
import numpy as np
import psutil

usr = "AA"
computer = "BB"
cpu_script = os.path.join(os.getcwd(),"cpu_script.py")
test = subprocess.check_output("ssh -X " + usr + "@" + computer + 
         "python3 -u - < " + cpu_script,shell=True).strip()

由于 cpu_percent 的输出通常在一个列表中,我希望我的 "test" 变量是一个列表,但我真正得到的是一个字节:

input(test)
>> b'[4.0, 5.0, 7.0, 10.9, 18.4, 1.0, 4.0, 3.0]'
input(type(test))
>> <class 'bytes'>

在这里我已经设法弯曲所有东西最终得到一个数组(解码+替换+np.fromstring),但它远不能令人满意:

tmp = test.decode("utf-8")
input(tmp)
>> [4.0, 5.0, 7.0, 10.9, 18.4, 1.0, 4.0, 3.0]
input(type(tmp))
>> <class 'str'>

tmp = (tmp.replace('[','')).replace(']','')
result = np.fromstring(tmp, sep=',')
input(result)
>> [ 4.   5.   7.  10.9 18.4  1.   4.   3. ]
input(type(result))
>> <class 'numpy.ndarray'>

难道我不能直接使用列表或数组形式的 subprocess.check_output 变量吗?我错过了什么?

此外,如果有一种方法可以避免定义 cpu_script,从而直接在子进程中传递 python 命令,我会很感兴趣!我现在所有的尝试都失败了,这里棘手的部分是同时存在 ssh 连接和 python3 控制台命令,后跟 python 命令。

感谢您的帮助!

底层 python 程序 "serialized" 输出为文本。

check_output returns一个需要解码的bytes对象,然后"unserialize".

我建议:

import ast

result = ast.literal_eval(test.decode())

最好的方法是将此子python 脚本作为模块调用。在这种情况下,您不必 运行 a subprocess/serialize/unserialize。只需导入子模块,调用一个函数并得到一个真正的 list 作为结果。当然,在ssh子进程调用的情况下,你不能。

但是你可以改进这个丑陋的代码注入 prone/unsafe check_output 调用需要 shell=True 通过传递打开的 python 文件的文件句柄来执行,提供输出到 check_output 的输入,并使用字符串列表而不是字符串作为参数:

with open(cpu_script,"rb") as f:
    test = subprocess.check_output(["ssh","-X",usr + "@" + computer,"python3","-u","-"],stdin=f)

后面是解码+求值代码