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)
后面是解码+求值代码
我愿意确定一堆 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)
后面是解码+求值代码